Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 4 of 4

Thread: Simple multithreading using wait and notify

  1. #1
    Junior Member
    Join Date
    Jul 2013
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Simple multithreading using wait and notify

    Can anyone read the following code and see why I can't let 3 threads count to 60? Order in which they execute (increment to 20) is not important but most of the times I only see two of them do. The only condition is I have to use wait and notify to make it work.

    class MyBetterThread extends Thread {
     
    	  private static int count = 0;
    	  private static boolean can_go = true;
     
    	  private String name;	
     
    	  public void incrementby(int j)throws InterruptedException {
     
    		  synchronized (this) {
    			  while (!can_go) {
    				  wait();  // release the lock of this object
    			  }
    			  can_go = false;
    			  for (int i = 1; i <= j; ++i) {  // try 5, 10, 20
    				  count += 1;
    				  System.out.println("Count from " + name + ": " + count);
    			  }
    			  can_go = true;
    			  notify();
    		  }
    	   }
     
    	   public MyBetterThread(String name) {   // constructor
    	      this.name = name;
    	   }
     
    	   @Override
    	   public void run() {
    		   try {
    			   incrementby(20);
    		   } catch (InterruptedException e) {} 
    	  }
    }
     
    class MyBetterThreadTest {
        public static void main(String[] args) {
            Thread[] mybetterthreads = {
               new MyBetterThread("Thread 1"),
               new MyBetterThread("Thread 2"),
               new MyBetterThread("Thread 3")
            };
            for (Thread t : mybetterthreads) {
               t.start();
            }
        }
    }


  2. #2
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,517
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Simple multithreading using wait and notify

    Every time I run it, I get:
    Count from Thread 1: 1
    Count from Thread 1: 2
    Count from Thread 1: 3
    Count from Thread 1: 4
    Count from Thread 1: 5
    Count from Thread 1: 6
    Count from Thread 1: 7
    Count from Thread 1: 8
    Count from Thread 1: 9
    Count from Thread 1: 10
    Count from Thread 1: 11
    Count from Thread 1: 12
    Count from Thread 1: 13
    Count from Thread 1: 14
    Count from Thread 1: 15
    Count from Thread 1: 16
    Count from Thread 1: 17
    Count from Thread 1: 18
    Count from Thread 1: 19
    Count from Thread 1: 20
    Count from Thread 2: 21
    Count from Thread 2: 22
    Count from Thread 2: 23
    Count from Thread 2: 24
    Count from Thread 2: 25
    Count from Thread 2: 26
    Count from Thread 2: 27
    Count from Thread 2: 28
    Count from Thread 2: 29
    Count from Thread 2: 30
    Count from Thread 2: 31
    Count from Thread 2: 32
    Count from Thread 2: 33
    Count from Thread 2: 34
    Count from Thread 2: 35
    Count from Thread 2: 36
    Count from Thread 2: 37
    Count from Thread 2: 38
    Count from Thread 2: 39
    Count from Thread 2: 40
    Count from Thread 3: 41
    Count from Thread 3: 42
    Count from Thread 3: 43
    Count from Thread 3: 44
    Count from Thread 3: 45
    Count from Thread 3: 46
    Count from Thread 3: 47
    Count from Thread 3: 48
    Count from Thread 3: 49
    Count from Thread 3: 50
    Count from Thread 3: 51
    Count from Thread 3: 52
    Count from Thread 3: 53
    Count from Thread 3: 54
    Count from Thread 3: 55
    Count from Thread 3: 56
    Count from Thread 3: 57
    Count from Thread 3: 58
    Count from Thread 3: 59
    Count from Thread 3: 60
    Isn't that what you're looking for?

  3. #3
    Junior Member
    Join Date
    Jul 2013
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Simple multithreading using wait and notify

    Ideally it's doing it consistently like you said. But it does this most of the time in my Eclipse run environment:

    Count from Thread 1: 1
    Count from Thread 1: 2
    Count from Thread 1: 3
    Count from Thread 1: 4
    Count from Thread 1: 5
    Count from Thread 1: 6
    Count from Thread 1: 7
    Count from Thread 1: 8
    Count from Thread 1: 9
    Count from Thread 1: 10
    Count from Thread 1: 11
    Count from Thread 1: 12
    Count from Thread 1: 13
    Count from Thread 1: 14
    Count from Thread 1: 15
    Count from Thread 1: 16
    Count from Thread 1: 17
    Count from Thread 1: 18
    Count from Thread 1: 19
    Count from Thread 1: 20
    Count from Thread 3: 21
    Count from Thread 3: 22
    Count from Thread 3: 23
    Count from Thread 3: 24
    Count from Thread 3: 25
    Count from Thread 3: 26
    Count from Thread 3: 27
    Count from Thread 3: 28
    Count from Thread 3: 29
    Count from Thread 3: 30
    Count from Thread 3: 31
    Count from Thread 3: 32
    Count from Thread 3: 33
    Count from Thread 3: 34
    Count from Thread 3: 35
    Count from Thread 3: 36
    Count from Thread 3: 37
    Count from Thread 3: 38
    Count from Thread 3: 39
    Count from Thread 3: 40

    Is there a reason why it's not consistent in Eclipse while it is in a different run environment?

  4. #4
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,895
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Simple multithreading using wait and notify

    Your code has several race conditions and dead-locks (which explains why GregBrannon got "desired" results and you didn't).

    1. You're synchronizing on different objects. Thus every thread is allowed through the synchronized block( a.k.a. it does nothing but hurt performance).

    2.

    // initially: can_go = true
    while (!can_go) {
    	wait();  // release the lock of this object
    }
    can_go = false;

    Multiple threads could reach the compare statement at the same time. They would determine can_go == true, and skip the while loop. These concurrent threads then all set can_go to false. However, multiple threads don't have to pass the while loop at the same time. If any thread gets trapped in this while loop, they will dead-lock, never to finish because no other thread will ever notify that thread (they all notify their own unique thread objects).

    At this point, you have entered undefined land, where your computer is allowed to catch fire spuriously. Writes can over-ride writes, two writes could combine their bits and give garbage results, or worse of all nothing could go wrong until you release your program and planes start falling out of the sky (a bit of an exaggeration, but multi-threaded programs are extremely hard to debug after-wards so we do our best to encourage programmers to get it right the first time ).

    Personally, I wouldn't use any locking here at all, but I would use atomics. However, they are generally harder to get right so we'll ignore that they exist for now.

    What you need to do is have a common object you can synchronize on. Since synchronized blocks guarantee mutual exclusion, using an extra boolean variable is just asking for trouble. You're very likely to end up with dead-locks, data races, or all sorts of nastiness.

    Here's a simplistic fixed solution (not a full solution, but it's very close to a complete solution):

    class MyBetterThread extends Thread {
        private static Object my_lock = new Object();
     
        public void incrementby(int j)
        {
            synchronized(my_lock)
            {
                // this section is now guarded by mutual exclusion, a.k.a. guaranteed only one thread will be in here
                // do your work here
            }
        }
    }

Similar Threads

  1. Help wanted using wait() and notify()
    By sandramo in forum Java Theory & Questions
    Replies: 7
    Last Post: March 29th, 2013, 12:19 PM
  2. wait(), sleep() and notify()
    By evthim in forum Threads
    Replies: 3
    Last Post: October 30th, 2012, 11:37 AM
  3. How to notify() and proceed past wait()
    By kernel_klink in forum What's Wrong With My Code?
    Replies: 5
    Last Post: February 21st, 2012, 07:40 PM
  4. let first thread through, the rest has to wait
    By hamsterofdeath in forum Threads
    Replies: 0
    Last Post: November 19th, 2010, 01:32 PM
  5. How to use and notify
    By Saeid in forum Threads
    Replies: 4
    Last Post: August 12th, 2010, 11:12 AM