Results 1 to 17 of 17
  1. #1
    turanan is offline Member
    Join Date
    Mar 2009
    Posts
    19
    Rep Power
    0

    Default thread execution one after another

    Greetings!

    I have encountered a certain problem while reading the chapter about threads. Here's an exercise:

    Two threads should do thinks strictly in turn - for example;

    Thread one prints stuff
    Thread two prints stuff
    Thread one prints stuff
    Thread two prints stuff

    and so on.

    Buy making a printing method synchronized I was able to achieve the following:

    Thread one prints stuff
    Thread one prints stuff
    Thread one prints stuff
    Thread two prints stuff
    Thread two prints stuff
    Thread two prints stuff

    This is the code I wrote:

    public class NewOneByOneThread implements Runnable {
    ....private String stuff = " printing material";

    ....public static void main(String[] args) {
    ........NewOneByOneThread myRunnable = new NewOneByOneThread();

    ........Thread tOne = new Thread(myRunnable);
    ........Thread tTwo = new Thread(myRunnable);

    ........tOne.setName("First thread");
    ........tTwo.setName("Second thread");

    ........tOne.start();
    ........tTwo.start();
    ....}

    ....public void run() {
    ........for (int i = 1; i <= 3; i++) {
    ............printStuff(i);
    ........}
    ....}

    ....private synchronized void printStuff(int i) {
    ........System.out.print(Thread.currentThread().ge tName() + stuff);
    ........try {
    ............Thread.sleep(500);
    ........} catch (InterruptedException e) {
    ............e.printStackTrace();
    ........}
    ........System.out.println(" for the " + i + ". time" + Thread.currentThread().getName());
    ....}
    }

    How can I force my two thread to run turn by turn? I tried to use wait and notify, but I ended up with a lot of exceptions. yield() method didn't do the trick for me, but again this might have been me using the code incorrectly.

    If someone could please provide an easy example with threads that run one by one, that would be jolly swell of you.

    I realize there might be two runnable classes needed.
    Last edited by turanan; 03-16-2009 at 02:31 PM.

  2. #2
    CJSLMAN's Avatar
    CJSLMAN is offline Moderator
    Join Date
    Oct 2008
    Location
    Mexico
    Posts
    1,159
    Rep Power
    8

    Default Is it alive?

    I haven't tried it, but you might want to look at the isAlive() method:
    Thread (Java 2 Platform SE v1.4.2))
    Java Code:
    if (thread.isAlive())
    Another link with an example:
    Determining When a Thread Has Finished (Java Developers Almanac Example)

    Luck,
    CJSL
    Chris S.
    Difficult? This is Mission Impossible, not Mission Difficult. Difficult should be easy.

  3. #3
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    Quote Originally Posted by turanan View Post
    I tried to use wait and notify, but I ended up with a lot of exceptions.
    Such as? The exceptions are telling you important information. learn to analyze them.

    My *guess* is that you failed to synchronize around your "wait" and "notify" methods, and ended up with illegal monitor state exceptions.

  4. #4
    sandeepsai39 is offline Member
    Join Date
    Feb 2009
    Posts
    96
    Rep Power
    0

    Default

    I don't know it is a better way or not ,but writing
    Thread.yield() after printStuff(i) in run() method gives your requiremnet.
    i.e
    //
    printStuff(i);
    Thread.yield();
    //
    I am giving this because i want to share my ideas and i want to know is there any problem ,when we write code like this.
    Last edited by sandeepsai39; 03-14-2009 at 09:26 AM.

  5. #5
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    In regards to "Thread.yield", I have yet to find any use for it in my ~14 years of Java programming, and I do tons of parallel programming on multiple platforms.

  6. #6
    turanan is offline Member
    Join Date
    Mar 2009
    Posts
    19
    Rep Power
    0

    Default using wait() and notify()

    OK, I've tried to rewrite this code using wait() and notify()

    public class OneByOneMain {
    ....public static String stuff = " printing material";

    ....public void primal() {
    ........OneByOneFirstThread myFirstRunnable = new OneByOneFirstThread();
    ........OneByOneSecondThread mySecondRunnable = new OneByOneSecondThread();

    ........Thread tOne = new Thread(myFirstRunnable);
    ........Thread tTwo = new Thread(mySecondRunnable);

    ........tOne.setName("First thread");
    ........tTwo.setName("Second thread");

    ........tTwo.start();

    ........tOne.start();
    ....}

    ....public static void printStuff(int i) {
    ........System.out.print(Thread.currentThread().ge tName() + stuff);
    ........try {
    ............Thread.sleep(500);
    ........} catch (InterruptedException e) {
    ............e.printStackTrace();
    ........}
    ........System.out.println(" for the " + i + ". time" + Thread.currentThread().getName());
    ....}
    }

    public class OneByOneFirstThread implements Runnable {
    ....public void run() {
    ........for (int i = 0; i < 10; i++) {
    ............synchronized (OneByOneMain.stuff) {
    ................OneByOneMain.printStuff(i);
    ................OneByOneMain.stuff.notifyAll();
    ............}
    ............try {
    ................Thread.currentThread().wait(50);
    ............} catch (InterruptedException e) {
    ................e.printStackTrace();
    ............}
    ........}
    ....}
    }

    public class OneByOneSecondThread implements Runnable {
    ....public void run() {
    ........for (int i = 0; i < 10; i++) {
    ............synchronized (OneByOneMain.stuff) {
    ................OneByOneMain.printStuff(i);
    ................try {
    ....................OneByOneMain.stuff.wait();
    ................} catch (InterruptedException e) {
    ....................e.printStackTrace();
    ................}
    ............}
    ........}
    ....}
    }

    which still doesn't give me the desired result. This code produces one of two results:
    either
    First thread printing material
    or
    Second thread printing material

    and then the program finishes with code 0

    Can someone please tell me where the mistake could be? And what should I do to fix it?

  7. #7
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    It may be beneficial to have a global variable setup that gets updated when a Thread has finished, and using an if statement before your thread executes to see what that global variable is set to. I'm in a class at the moment so I can't give the attention needed to write out an example, but I think you can get the idea.

    Also, you can use the Code feature to indent whatever code you copy and paste, so you won't have to use the '.' to indent for you. It is not available in the quick reply.
    Last edited by Moncleared; 03-16-2009 at 03:27 PM.

  8. #8
    turanan is offline Member
    Join Date
    Mar 2009
    Posts
    19
    Rep Power
    0

    Default

    Quote Originally Posted by Moncleared View Post
    It may be beneficial to have a global variable setup that gets updated when a Thread has finished, and using an if statement before your thread executes to see what that global variable is set to. I'm in a class at the moment so I can't give the attention needed to write out an example, but I think you can get the idea.
    I would greatly appreciate if you could find some time to post an example later, when you have spare time.

    But I can't quite say I got the idea with a global variable. My code doesn't even do the for cycles. It just prints once and then completes somehow.

  9. #9
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    I'm still a bit confused on your desired results, let me see if I have this straight. You want to pause in each for loop of the thread and wait for the opposite thread to print once and alternate back and forth.
    Example:
    Thread1printstuff
    Thread2printstuff
    Thread1printstuff
    Thread2printstuff
    Thread1printstuff
    Thread2printstuff

    Etc?

  10. #10
    turanan is offline Member
    Join Date
    Mar 2009
    Posts
    19
    Rep Power
    0

    Default

    Quote Originally Posted by Moncleared View Post
    I'm still a bit confused on your desired results, let me see if I have this straight. You want to pause in each for loop of the thread and wait for the opposite thread to print once and alternate back and forth.
    Example:
    Thread1printstuff
    Thread2printstuff
    Thread1printstuff
    Thread2printstuff
    Thread1printstuff
    Thread2printstuff

    Etc?
    Exactly right, that's what I'm trying to get.

  11. #11
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    This is probably not the proper way, probably considered a more brute force way. This will get the idea of the global variable across though.

    Java Code:
    public class OneByOneMain {
    	public static String stuff = " printing material";
    	public static boolean cthread = true;
    	public static void main(String args[]){
    		primal();
    	}
    	public static void primal() {
    		OneByOneFirstThread myFirstRunnable = new OneByOneFirstThread();
    		OneByOneSecondThread mySecondRunnable = new OneByOneSecondThread();
    
    		Thread tOne = new Thread(myFirstRunnable);
    		Thread tTwo = new Thread(mySecondRunnable);
    
    		tOne.setName("First thread");
    		tTwo.setName("Second thread");
    
    		tTwo.start();
    		tOne.start();
    	}
    
    	public static void printStuff(int i) {
    		System.out.println(Thread.currentThread().getName() + stuff);
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		//System.out.println(" for the " + i + ". time" + Thread.currentThread().getName());
    	}
    }
    
    class OneByOneFirstThread implements Runnable {
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			if(OneByOneMain.cthread==true) {
    				OneByOneMain.printStuff(i);
    				OneByOneMain.cthread=false;
    			}else
    				i--;
    		}
    	}
    }
    
    class OneByOneSecondThread implements Runnable {
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			if(OneByOneMain.cthread==false) {
    				OneByOneMain.printStuff(i);
    				OneByOneMain.cthread=true;
    
    			}else
    				i--;
    		}
    	}
    }
    Part of the problem with this code is that you could easily loose track of i, or if you lost track of your global boolean. If you know the specific order in which things should happen, such as we do here we can easily manipulate it to work in our favor. But when you start adding waits and sleeps or manipulating these threads in other ways, you risk the little bit of security we have. Just keep these ideas in mind as you advance this project, I removed your wait commands as I saw no use for them, if you need them added in let me know.

    I should probably explain how this code works if it is not obvious:
    We have a global variable cthread which is just a boolean. If it is true, it pretty much is telling us that Thread1 should be printing currently. If that is the case, right after thread1 prints, it should change that global variable to false, so it no longer prints. It is also the case that this thread is running when it is not allowed to print, therefore we have an else that subtracts 1 from i to keep us in position each time we pass through this for loop. Otherwise, you'd likely get 1 print statement being the first one, since it would run through all 10 loops instantly. If you need more explanation, let me know.

    Just a couple of side notes, if you want to pause a specific thread listed above:

    tTwo.sleep(1000); // 1 second sleep on the second thread
    tOne.sleep(1000); // 1 second sleep on the first thread

    Let me know if this helps
    Last edited by Moncleared; 03-16-2009 at 04:11 PM. Reason: Clarifications

  12. #12
    turanan is offline Member
    Join Date
    Mar 2009
    Posts
    19
    Rep Power
    0

    Thumbs up

    D:D

    That is a brute :D

    But everything in this code is completely understandable and logical.

    The most brute thing in my opinion is that one thread will keep looping pointlessly until the marker is changed. But it works nether the less :D

    I just wish I could do the same using synchronization...
    Last edited by turanan; 03-16-2009 at 04:20 PM.

  13. #13
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    Yea i was just reviewing the entire thread and noticed you were working specifically on synchronization. I haven't touched that yet, are you going off a guide?

    And yes; not only does one thread loop pointlessly they both do. By the nature of threads they run until they die, which is when they've completed their tasks. I'm not sure how that synchronization affects the for loop, whether it stops and waits for it or what. I'll have to check into it a bit.

    Sorry I couldn't help more.

  14. #14
    turanan is offline Member
    Join Date
    Mar 2009
    Posts
    19
    Rep Power
    0

    Default

    Quote Originally Posted by Moncleared View Post
    Yea i was just reviewing the entire thread and noticed you were working specifically on synchronization. I haven't touched that yet, are you going off a guide?

    And yes; not only does one thread loop pointlessly they both do. By the nature of threads they run until they die, which is when they've completed their tasks. I'm not sure how that synchronization affects the for loop, whether it stops and waits for it or what. I'll have to check into it a bit.

    Sorry I couldn't help more.
    Yeah, I actually am on the last chapter of SCJP course. I have this manual from Sun and the 9th chapter is all about threads.

    This exercise is was one of several I have on threads. One of them was to emulate a dead lock situation, which was quite easy compared to this one. I still have one more exercise, but I have no idea how to do that one.

    And you've helped me out a lot anyway, I'll tell you how my teacher will react when he'll see that code :D
    Last edited by turanan; 03-16-2009 at 04:42 PM.

  15. #15
    turanan is offline Member
    Join Date
    Mar 2009
    Posts
    19
    Rep Power
    0

    Default synchronized example

    So, to continue the dilemma, can someone please give an example of the code Moncleared has come up with, only using synchronized and possibly wait() and notify() ?

    Java Code:
    public class OneByOneMain {
        public static boolean cthread;
        public static String stuff = " printing material";
    
        public void primal() {
            OneByOneFirstThread myFirstRunnable = new OneByOneFirstThread();
            OneByOneSecondThread mySecondRunnable = new OneByOneSecondThread();
    
            Thread tOne = new Thread(myFirstRunnable);
            Thread tTwo = new Thread(mySecondRunnable);
    
            tOne.setName("First thread");
            tTwo.setName("Second thread");
    
            tTwo.start();
    
            tOne.start();
        }
    
        public static void printStuff(int i) {
            System.out.print(Thread.currentThread().getName() + stuff);
    
            System.out.println(" for the " + i + ". time" + Thread.currentThread().getName());
        }
    }
    
    public class OneByOneFirstThread implements Runnable {
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			if(OneByOneMain.cthread == false) {
    				OneByOneMain.printStuff(i);
    				OneByOneMain.cthread = true;
    
    			}else
    				i--;
    		}
    	}
    }
    
    public class OneByOneSecondThread implements Runnable {
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			if(OneByOneMain.cthread == true) {
    				OneByOneMain.printStuff(i);
    				OneByOneMain.cthread = false;
    			}else
    				i--;
    		}
    	}
    }
    This is the code that Moncleared came up with which does exactly what I needed to achieve - forces threads to work in turn. However, this code uses brute looping, and the idea is to make it work using synchronized.

    This is my code I wrote with synchronized, but it doesn't work correctly. Maybe you could correct my code, which could turn out easier, than writing a new example.

    Java Code:
    public class OneByOneMain {
        public static boolean cthread;
        public static String stuff = " printing material";
    
        public void primal() {
            OneByOneFirstThread myFirstRunnable = new OneByOneFirstThread();
            OneByOneSecondThread mySecondRunnable = new OneByOneSecondThread();
    
            Thread tOne = new Thread(myFirstRunnable);
            Thread tTwo = new Thread(mySecondRunnable);
    
            tOne.setName("First thread");
            tTwo.setName("Second thread");
    
            tTwo.start();
    
            tOne.start();
        }
    
        public static void printStuff(int i) {
            System.out.print(Thread.currentThread().getName() + stuff);
    
            System.out.println(" for the " + i + ". time" + Thread.currentThread().getName());
        }
    }
    
    public class OneByOneFirstThread implements Runnable {
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (OneByOneMain.stuff) {
                    OneByOneMain.printStuff(i);
                    OneByOneMain.stuff.notifyAll();
                }
            }
        }
    }
    
    public class OneByOneSecondThread implements Runnable {
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (OneByOneMain.stuff) {
                    OneByOneMain.printStuff(i);
                    try {
                        OneByOneMain.stuff.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

  16. #16
    Join Date
    Sep 2010
    Posts
    1
    Rep Power
    0

    Default

    Guys try this one
    <code>
    public class OneByOneMain {
    public static boolean cthread;
    public static String stuff = " printing material";

    public static void main(String args[]) {
    OneByOneFirstThread myFirstRunnable = new OneByOneFirstThread();
    OneByOneSecondThread mySecondRunnable = new OneByOneSecondThread();

    Thread tOne = new Thread(myFirstRunnable);
    Thread tTwo = new Thread(mySecondRunnable);

    tOne.setName("First thread");
    tTwo.setName("Second thread");

    tTwo.start();

    tOne.start();
    }

    public static void printStuff(int i) {
    System.out.print(Thread.currentThread().getName() + stuff);

    System.out.println(" for the " + i + ". time" + Thread.currentThread().getName());
    }
    }

    class OneByOneFirstThread implements Runnable {
    public void run() {
    for (int i = 0; i < 10; i++) {
    synchronized (OneByOneMain.stuff) {
    OneByOneMain.printStuff(i);
    try {
    OneByOneMain.stuff.notifyAll();
    OneByOneMain.stuff.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }

    class OneByOneSecondThread implements Runnable {
    public void run() {
    for (int i = 0; i < 10; i++) {
    synchronized (OneByOneMain.stuff) {
    OneByOneMain.printStuff(i);
    try {
    OneByOneMain.stuff.notifyAll();
    OneByOneMain.stuff.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    </code>

    o/p:-
    First thread printing material for the 0. timeFirst thread
    Second thread printing material for the 0. timeSecond thread
    First thread printing material for the 1. timeFirst thread
    Second thread printing material for the 1. timeSecond thread
    First thread printing material for the 2. timeFirst thread
    Second thread printing material for the 2. timeSecond thread
    First thread printing material for the 3. timeFirst thread
    Second thread printing material for the 3. timeSecond thread
    First thread printing material for the 4. timeFirst thread
    Second thread printing material for the 4. timeSecond thread
    First thread printing material for the 5. timeFirst thread
    Second thread printing material for the 5. timeSecond thread
    First thread printing material for the 6. timeFirst thread
    Second thread printing material for the 6. timeSecond thread
    First thread printing material for the 7. timeFirst thread
    Second thread printing material for the 7. timeSecond thread
    First thread printing material for the 8. timeFirst thread
    Second thread printing material for the 8. timeSecond thread
    First thread printing material for the 9. timeFirst thread
    Second thread printing material for the 9. timeSecond thread

  17. #17
    Join Date
    May 2012
    Posts
    1
    Rep Power
    0

    Default Re: thread execution one after another

    Unfortunately, the above code is incorrect. The reason is that the first notifyAll() call to be executed by the thread that first gets the lock on OneByOneMain.stuff, goes wasted (the second thread cannot be in the wait() call to listen to that first notifyAll(), since it doesn't have the lock on OneByOneMain.stuff so as to have entered its own notifyAll() and then wait() call.) For this reason, when both threads run their "for" loops (i=0...9) the thread to have entered called "printStuff()" second, won't be able to run its final iteration, because it is one notification short. And so the program hangs without finishing (you may of course press Ctrl-C to terminate).

Similar Threads

  1. Difference between Thread.yield() and Thread.sleep() methods
    By Nageswara Rao Mothukuri in forum New To Java
    Replies: 12
    Last Post: 07-30-2010, 06:37 PM
  2. passing a value from parent thread to child thread
    By sachinj13 in forum Threads and Synchronization
    Replies: 7
    Last Post: 09-07-2008, 10:06 PM
  3. data from the main/GUI thread to another runnin thread...
    By cornercuttin in forum Threads and Synchronization
    Replies: 2
    Last Post: 04-23-2008, 11:30 PM
  4. Replies: 0
    Last Post: 01-28-2008, 08:02 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •