i want to test java multithread ,but only one thread run - java

public class ThreadText
{
public static void main(String[] args)
{
windows w=new windows();
Thread t1=new Thread(w);
Thread t2=new Thread(w);
Thread t3=new Thread(w);
Thread t4=new Thread(w);/*four threads*/
t1.start();
t2.start();
t3.start();
t4.start();
}
}
i want to use four windows to sale 1000 tickets
class windows implements Runnable
{
int tickets=1000;
public void run()
{
synchronized(this)
{
while(tickets>0)
{
System.out.println(Thread.currentThread().getName()+" is saling"+tickets);
tickets--;
}
}/*i think problem is here*/
}
}
when i don't use synchronized ,all threads run,but results are wrong.
some tickets number are same.the correct result is that every window gets different ticket number.
Thanks

When you synchronize the entire loop, the first thread will get the lock and will count down to 0. The other 3 threads will wait until first thread releases the lock, at which point there's nothing left for them to do. In effect, the result is single-threaded.
To work correctly, you need to synchronize inside the loop, so the other threads can work too.
However, the first thread may still be too fast, so that it ends up doing all the work. To better simulate what you want, add a delay outside the synchronize block (making a sale takes time, you know). Added minimum delay of 1ms in the code below.
And finally, Java naming convention is for class names to start with an Uppercase letter, so it should be named Windows.
class Windows implements Runnable {
private int tickets = 1000;
#Override
public void run() {
String threadName = Thread.currentThread().getName();
for (;;) { // loop forever
synchronized (this){
if (this.tickets == 0)
break;
System.out.println(threadName + " is saling " + this.tickets);
this.tickets--;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
break;
}
}
}
}
OUTPUT
Thread-0 is saling 1000
Thread-2 is saling 999
Thread-3 is saling 998
Thread-1 is saling 997
Thread-0 is saling 996
Thread-1 is saling 995
Thread-2 is saling 994
Thread-3 is saling 993
Thread-0 is saling 992
Thread-1 is saling 991
Thread-3 is saling 990
Thread-2 is saling 989
. . .
Thread-2 is saling 11
Thread-1 is saling 10
Thread-0 is saling 9
Thread-3 is saling 8
Thread-0 is saling 7
Thread-1 is saling 6
Thread-2 is saling 5
Thread-1 is saling 4
Thread-0 is saling 3
Thread-3 is saling 2
Thread-2 is saling 1

You do need to synchronize due to the tickets member being accessed by multiple threads. But because you are basing the run method on while tickets > 0, only 1 thread will ever run until the end. One solution would be to tie the execution of the thread to another variable and have the run method just decrement tickets once, then sleep so other threads can have a chance to run. For example, if you refactor your windows class as follows, then it will do what I think you want it to do.
class windows implements Runnable {
volatile boolean finished = false;
int tickets = 1000;
public void run() {
while(!finished) {
synchronized(this) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName()+" is selling " + tickets);
tickets--;
if (tickets <= 0) {
finished = true;
}
}
}
try {
Thread.sleep(10);
}
catch(InterruptedException ex) {
}
}
}
}

What you are experiencing is known as a race condition. That means due to the order of threads operating, you can get two threads thinking they decremented something but only one did, etc.
To address this, you have two options:
synchronized -- which is pretty heavy handed, and unless you put it at the smallest critical section is going to be too much.
AtomicInteger -- which makes sure that the integer is incremented or decremented safely across threads.
To fix your example and still use synchronized, your code should look like this:
class windows implements Runnable
{
int tickets=1000;
public void run()
{
while(tickets>0)
{
synchronized(this)
{
System.out.println(Thread.currentThread().getName()+" is saling"+tickets);
tickets--;
}
}
}
}
Of course, the down side to that is you have to remember to synchronize all access to the variable.
Using AtomicInteger the process is much easier to control:
class windows implements Runnable
{
AtomicInteger tickets = new AtomicInteger(1000);
public void run()
{
while(tickets.get() > 0)
{
System.out.println(Thread.currentThread().getName()
+ " is saling" + tickets.decrementAndGet());
}
}
}

From your code I understand that you are trying to replicate a Sales Window in Real Life for the Tickets.
Analogy (Look at the Image Link at the bottom of answer):
A place for sales of Tickets (Say, concert Tickets). This place has multiple Sections/Windows from where the exchange of money happens and the concert ticket is provided. Behind the Window there is a person that actually takes the money and gives u the ticket. Since in your example there is nothing related to money, so this is just a one sided exchange. Basically the person behind the window gives the ticket when ever a customer comes (Customer coming is like thread getting executed in your example).
There are only limited finite number of Ticket, each having a unique ticket number between 1 to 1000.
Your code has same instance of Runnable Window. And this same instance is provided for execution to all threads (All different Instances of Thread).
So your Real Life Design becomes like :
That the same person will give you the tickets from Window 1, 2, 3 etc. But at one time only one window can be taken care by this person.
So making your code effectively to run as Single Processer/Core code but poorer performance than the sequential code as the thread switching (if occurred) will have more overheads.
Now lets say we had multiple sales person - One for each window. Then the question becomes of NOT selling the same ticket by different sales person (Race Condition).
For this all the sales person have to take a ticket from a box one at a time. I.E. the part of getting the ticket is the only part that needs to be synchronized. This would be best achieved by Atomic Integers. Other answers have more than required chunk of code with in their synchronized blocks. This part has been answered (as per me) by #Berin Loritsch reply.
class TicketSeller /* Not windows*/ implements Runnable {
AtomicInteger tickets = new AtomicInteger(1000);
public void run() {
while (tickets.get() > 0) {
System.out.println(Thread.currentThread().getName()
+ " is saling" + tickets.decrementAndGet());
}
}
}
public class ThreadText {
public static void main(String[] args) {
Thread t1 = new Thread(new TicketSeller());
Thread t2 = new Thread(new TicketSeller());
Thread t3 = new Thread(new TicketSeller());
Thread t4 = new Thread(new TicketSeller());
/*four threads, four windows from where the ticket can be provided by 4
different TicketSellers*/
t1.start();
t2.start();
t3.start();
t4.start();
}
}
With this when a different thread comes into execution or multiple threads run in parallel the thread is not put to unnecessary sleep (And sleep doesn't even confirm avoiding of the race condition, by the way) and is blocked from execution for only a limited area of the code, i.e. tickets.get().
Of course you can go a few steps ahead an optimize this even more. But that would require a lot more deeper understanding and complex thinking. E.g. Sales person is allocated a certain number of tickets. And ticket shuffling happens so that to optimize that maximum number of tickets are sold in quickest execution time by something managing the tickets that each SalePerson has.
Ticket Sale Window Example :
https://www.google.com/imgres?imgurl=https%3A%2F%2Fimage.shutterstock.com%2Fimage-photo%2Fthree-windows-stadium-ticket-offices-260nw-1776188525.jpg&imgrefurl=https%3A%2F%2Fwww.shutterstock.com%2Fsearch%2Ftickets%2Bwindow&tbnid=BW8bA0aSqJTxaM&vet=12ahUKEwiVvvrmp47zAhU6g0sFHW8TCekQMygEegUIARC9AQ..i&docid=QQwLjL01dRWDoM&w=390&h=280&q=Ticket%20Sale%20Window&ved=2ahUKEwiVvvrmp47zAhU6g0sFHW8TCekQMygEegUIARC9AQ

Related

Java thread output

public class oneThread extends Thread {
public void run()
{
System.out.println("geeks ");
try {
Thread.sleep(300);
}
catch (InterruptedException ie) {
}
System.out.println("forgeeks ");
}
public static void main(String[] args)
{
oneThread c1 = new oneThread();
oneThread c2 = new oneThread();
c1.start();
c2.start();
System.out.println(c1.isAlive());
System.out.println(c2.isAlive());
}
}
its real output is ->
geeks
true
true
geeks
forgeeks
forgeeks
how is this correct ?
I expected it to be ->
geeks
geeks
true
true
forgeeks
forgeeks
There are lots of legal execution sequences that could give rise to that output.
For example:
in main: c1.start()
in main: c2.start()
in thread 1: println("geeks")
in thread 1: sleep
in main: println(c1.isAlive()); println(c2.isAlive());
in thread 2: println("geeks")
in thread 2: sleep
in thread 1: println("for geeks")
in thread 2: println("for geeks")
JVM terminates since all threads have completed
Other possible execution sequences include:
Steps 3 and 4 could happen before step 2.
Thread 2 could be scheduled before thread 1.
Thread 2 could "overtake" thread 1 due to the sleep times being imprecise.
And so on.
These are all legal behaviors, and on some platforms you might actually encounter them.
This is perfectly valid behavior. The JVM is free to decide which Thread runs and when. Some of the things you should note is that starting a thread takes some time, and while Thread 2 is still starting, main keeps going and gets to its print. Also Threads can be put to sleep for a lengthy IO operation such as System.out.println, and another thread will run while the print is executing.

I'm trying to run threads whose run() method has for loop, some loops are being skipped only when sleep() is used.Can anybody please explain why?

I'm trying to run four threads. run() method has a for loop that loops 10 times.In each loop the shared resource "x" is increment by 1. When all threads die, the for loop should have run 4x10 =40 times and x value should equal 40.
That is not happening in all runs of the my code.Each time I run the code it prints a different value of x.Most of the output values of x range from 33 to 40.
Why is it not 40 in every run? Does that mean some for loop loops are being skipped? Is it caused due being blocked?
NOTE : this does not happen when sleep() is removed. It prints 40 every single time.
My code :
public class MyThreadImplementsRunnable implements Runnable{
int x =0;
public void run() {
for(int i=0;i<10;i++){
x = x+1;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("exception");
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThreadImplementsRunnable m = new MyThreadImplementsRunnable();
Thread t1 = new Thread(m,"first");
Thread t2= new Thread(m,"second");
Thread t3= new Thread(m,"third");
Thread t4= new Thread(m,"fourth");
t1.start();
t2.start();
t3.start();
t4.start();
//To make sure not to go the next statement unless all threads die
while(t1.isAlive()|| t2.isAlive()|| t3.isAlive()||t4.isAlive()){
}
//After all threads die
System.out.println("now all threads are dead");
//value of the shared resource x after all threads exit
System.out.println(m.x);
}
}
Some test runs gave the following results :
Output:
now all threads are dead
34
Output:
now all threads are dead
33
x = x + 1 loads the value of x from memory, adds 1 to it and then stores it in x. Lets say Thread t1 loads 30 and at the same time thread t2 loads 30 they both increment 30 by 1 and store 31 in x instead of 32.
Why it's always 40 without sleep can be caused by many things I hypothesize that it's caused by each of the threads running very quickly and finishing before the next one starts.
You also don't use volatile and there are visibility issues but for now lets not get into that. This is also something you need to learn if you want to write multi-threaded code.
You are using a shared resource(x) between threads which is bound to create many problems like data race, visibility.. Your answer will be always different
#oleg I don't think Volatile will help in this scenario

Multithreading start method

and this a normal thread program
class Counter implements Runnable {
private int currentValue;
public Counter() { currentValue = 0; }
public int getValue() { return currentValue; }
public void run() { // (1) Thread entry point
try {
while (currentValue < 5) {
System.out.println(Thread.currentThread().getName() + ": " + (currentValue++)); // (2) Print thread name.
Thread.sleep(250); // (3) Current thread sleeps.
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
System.out.println("Exit from thread: " + Thread.currentThread().getName());
}
}
//_______________________________________________________________________________
public class Client {
public static void main(String[] args) {
Counter counterA = new Counter(); // (4) Create a counter.
Thread worker = new Thread(counterA, "Counter A");// (5) Create a new thread.
System.out.println(worker);
worker.start(); // (6) Start the thread.
try {
int val;
do {
val = counterA.getValue(); // (7) Access the counter value.
System.out.println("Counter value read by " + Thread.currentThread().getName()+ ": " + val); // (8) Print thread name.
Thread.sleep(1000); // (9) Current thread sleeps.
} while (val < 5);
} catch (InterruptedException e) {
System.out.println("The main thread is interrupted.");
}
System.out.println("Exit from main() method.");
}
}
and the output is
Thread[Counter A,5,main]
Counter value read by main thread: 0
Counter A: 0
Counter A: 1
Counter A: 2
Counter A: 3
Counter value read by main thread: 4
Counter A: 4
Exit from thread: Counter A
Counter value read by main thread: 5
Exit from main() method.
My question is even though the worker thread was started initially before the Main thread enters it's try block, Main thread execution starts first and then when the Main thread goes to sleep child thread gets into action.
As this picture(taken from "A Programmer's Guide To Java SCJP Certification : A Comprehensive Primer 3rd Edition"
Author: Khalid A Mughal, Rolf W Rasmussen) depicts that when the start method is called on the thread it returns immediately.
Please explain this point that why on invoking start method it return immediately and does the thread get starts on calling the start method. As here on calling the start method it doesn't invoke run method of the class. So when does actually the thread starts ?
Also explain this " the call to the start() method is asynchronous."
there are three things that you are missing in your overall analysis.
Call to thread's start method is sequential not parallel. Its the call to run method of Thread that is concurrent. So if you have 5 statements in main method that call start, the 5ht is not going t be called first. Thats the 'happens before' guarantee that JVM specs give you. However the run method of 1 first may get called before or after the call to the second start statement. This depends as its more of a CPU time slicing issue rather than program execution.
When more than 1 thread runs in your program the order of output is in-deterministic. That's because they run in parallel. You can never be sure that the same program will run in same order on two machines or even in two runs on the same machine. In your question you have posted only 1 output. Run the program like 20 times one after another and match the output. I am sure 2 or 3 would be entirely different.
Finally, you are basing your analysis on the order or execution of your concurrent code. That's the biggest blooper programmer make. Concurrent programs are never intended to run in a specific order or sequence. Just try to make your Runnable work an atomic mutually exclusive task (mutually exclusive to the rest of program or even to other Runnables) and track its own execution. Dont mix Threads together.
You cannot directly enforce which Thread is executed/running when. Once you start it, it's handled on lower level(usually by OS) and the results may differ on different machine or even in different execution. If you need more control, you need to use some synchronization mechanism.
The thread is isn't started synchronously underneath the call to start(). It happens later (asynchronously). In other words, just because you called start() doesn't mean the thread has started.
They why and how are all implementation details, that may depend on JVM and/or OS implementations.

Java - Count in COUNTDOWNLATCH

While running each thread why does the countdown.getCount() always print '3' even after the previous thread has already called countdown.countDown() and reduced the Latch Count by 1?
I am kind of worndering how Java knows that the Latch Count has reached 0, so that it can release all the 3 threads.
import java.util.concurrent.CountDownLatch;
class b {
static final CountDownLatch countdown = new CountDownLatch(3);
public static void main(String[] args) {
for (int i = 0; i < 3; ++i) {
Thread t = new Thread() {
public void run() {
System.out.printf("Starting on %d other threads.\n",
countdown.getCount());
countdown.countDown();
System.out.printf("new on %d other threads.\n",
countdown.getCount());
try {
countdown.await(); // waits until everyone reaches this
// point
// System.out.println("Go again : "
// +countdown.getCount());
} catch (Exception e) {
}
}
};
t.start();
}
System.out.println("Go");
}
}
you are starting 3 threads in parallel. depending on how fast they start, they could all print "3" before any of the threads manages to call countDown() (at least for the "Starting on..." line). the "new on ..." line, however, should print out some range of numbers between 2 and 0.
It's absolutely possible that all three threads print "Starting on 3.." as the threads run in parallel, and the count doesn't change until a thread executed countDown(). To really understand what's going on, I suggest you prepend System.nanoTime() and thread name before your print statements as below:
...
Thread t = new Thread("Thread-" + i) {
...
System.out.printf("%d> %s: Starting on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
countdown.countDown();
System.out.printf("%d> %s: new on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
Sometimes you'd get an output like below which may give you the impression that Thread-2 is disregarding Thread-1's call to countDown:
1407489646569321000> Thread-0: Starting on 3 other threads.
1407489646569324000> Thread-1: Starting on 3 other threads.
1407489646602463000> Thread-1: new on 1 other threads.
1407489646569513000> Thread-2: Starting on 3 other threads.
1407489646602107000> Thread-0: new on 2 other threads.
1407489646603275000> Thread-2: new on 0 other threads.
However, that is not the case, and we can verify the correct order of operations by looking at the timestamp. The mixup in the output is due to inherent unpredictability in thread scheduling, depending on which thread gets the cpu splice.
Having said that, they may not always print 3, depending on thread scheduling or delays. As an example, try putting a Thread.sleep(..) as shown below:
public static void main(String[] args) throws Exception {
for (int i = 0; i < 3; ++i) {
Thread t = new Thread() {
public void run() {
/* As before */
}
};
t.start();
Thread.sleep(100); // Artificial Delay
}
}
Now you should see different results like below:!
1407490223575404000> Thread-0: Starting on 3 other threads.
1407490223607879000> Thread-0: new on 2 other threads.
1407490223676233000> Thread-1: Starting on 2 other threads.
1407490223676818000> Thread-1: new on 1 other threads.
1407490223777623000> Thread-2: Starting on 1 other threads.
1407490223778221000> Thread-2: new on 0 other threads.
Internally, the CountDownLatch maintains a first in, first out wait Queue (See. AbstractQueuedSynchronizer). The value of the count is synchronized, and the waiting threads are only released when the count becomes 0 or someother thread interrupts the waiting thread. This is the mechanism used by the latch to keep track of when all the threads have arrived at the latch.
If you're interested in understanding the latch in the context of testing, checkout http://razshahriar.com/2014/08/testing-asynchronous-code-in-java-with-countdownlatch/
Hope this helps clarify your investigation of the Program behaviour.

Simple Threads Behaviour in Java

/* Multiple Threads Executing
* Author Myth17
*/
class T1 implements Runnable
{
public void run()
{
for(int c=0;c<10;c++)
System.out.println(Thread.currentThread().getName()+" running....");
}
}
class T2 implements Runnable
{
public void run()
{
for(int c=0;c<10;c++)
System.out.println(Thread.currentThread().getName()+" running....");
}
}
class T3 implements Runnable
{
public void run()
{
for(int c=0;c<10;c++)
System.out.println(Thread.currentThread().getName()+" running....");
}
}
class Rt
{
public static void main(String args[])
{
T1 j1=new T1();
T2 j2=new T2();
T3 j3=new T3();
Thread w1=new Thread(j1);
w1.setName("S");
Thread w2=new Thread(j2);
w2.setName("N");
Thread w3=new Thread(j3);
w3.setName("M");
w1.start();
w2.start();
w3.start();
}
}
If the loop runs up to 3 in the three for loops, in Linux Java JVM each thread executes serially as SSSNNNMMM (9 lines).
I changed the loop to run up to 10 in each for loops. I was expecting 30 lines and a change in order. But strangely S never executes and program exits!!
Shouldn't S get its chance sooner or later? As what I have read is that apart from deamon threads JVM shuts only after user thread complete.
alt text http://img36.imageshack.us/img36/6646/69458021.png
Did you realize that there are 8 lines of N in your output folder and 10 lines of M. It seems that the output window just displays 18 lines. S runs but you cannot see it.
Can you try incrementing loop to 20 instead of 10. I guess you will just see 18 lines of M.
(It seems that the problem is just not having a scroll bar on output window. Resize should work if exists.)
In your snippet neither of the threads are daemon. And until you set the threads as daemon via Thread#setDaemon() all the threads will execute completely before the app exits.
Recheck your problem!!
This should have worked. You could put log in the run() methods or debug it using break points.
You only have 18 lines showing in the window.
All of the "S" lines have scrolled off, as well as two of the "N" lines.
I tried running your code on a Windows Sun JVM 1.6 and as expected, I got 30 lines. What kind of JVM are you using?
All non daemon threads should finish before the JVM exists.

Categories

Resources