3

I am learning Java but have trouble with synchronized. i want print list of numbers from many Java threads and have each thread go in order.I get problem when using synchronized because i not much understand. Can help understand?

I want output to see this but sometimes threads in wrong order.i want:

1-thread1
2-thread2
3-thread1
4-thread2
5-thread1
6-thread2
...
48-thread2
49-thread1

My broken codes:

public class ManyThreadsAdd {
    public static int index = 0;

    public static void main(String[] args) {
        ManyThreadsAdd myClass = new ManyThreadsAdd();
        Thread thread1 = new Thread(myClass.new RunnableClass());
        Thread thread2 = new Thread(myClass.new RunnableClass());

        thread1.start();
        thread2.start();
    }

    class RunnableClass implements Runnable {
        public synchronized void run() {
            while (index < 49) {
                try {
                    Thread.sleep(100);
                    System.out.println(index+"-" +Thread.currentThread());
                    index = index + 1;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 1
    You have to use `wait()` and `notify()`here. You need some sort of communication between threads to achieve your output. – TheLostMind Oct 16 '14 at 14:18
  • yes i try wait and notify but always wrong exception. Maybe common class to use wait and notify? – JoeJoeJoeJoe4 Oct 16 '14 at 14:39
  • you have to use a shared lock. see the accepted answer for http://stackoverflow.com/q/6017281/217324 . voting to close as a dupe of this since it is the same problem. i tried to pick a good one for you, but if this doesn't resolve your question there are plenty of other questions posted on this problem that have answers, google for "java multithreading even odd site:stackoverflow.com". – Nathan Hughes Oct 16 '14 at 15:11
  • You say you want to use "many" threads, but your example output shows two; are you using *exactly* two threads, or an arbitrary number of threads? Do you want the threads to execute in an *exact* round-robin fashion, e.g., `t1, t2, ..., tN, t1, t2, ..., tN`? The solution is a bit more complicated if you're coordinating an arbitrary number of threads. – Mike Strobel Oct 16 '14 at 15:20

2 Answers2

2

Firstly, multithreading by nature is asynchronous, you cannot specify the order in which these threads get executed. If you want output like below, use a loop:

1-thread1
2-thread2
3-thread1
4-thread2
5-thread1
6-thread2
...
48-thread2
49-thread1

Secondly, you gain nothing by adding the synchronized keyword in public synchronized void run(). This just means that at any time, only one thread at a time can call that method. As you are constructing new classes for each thread, this is meaningless.

Thirdly, if you did need to synchronise between your threads, use a queue to which you add tasks, and which your threads read one at a time.

PeterK
  • 1,697
  • 10
  • 20
2

It depends on what you want to do.

A simple way to alternate the order of the print is to synchronize on the same object, in this case you can use the index or any other object.

public class ManyThreadsAdd {
    public static AtomicInteger index = new AtomicInteger(0);

    public static void main(String[] args) {
        ManyThreadsAdd myClass = new ManyThreadsAdd();
        Thread thread1 = new Thread(myClass.new RunnableClass());
        Thread thread2 = new Thread(myClass.new RunnableClass());

        thread1.start();
        thread2.start();
    }

    class RunnableClass implements Runnable {
        public void run(){
            synchronized(index){
                while(index.get() < 49){
                    try {
                      Thread.sleep(100);
                      System.out.println(index.get()+"-" +Thread.currentThread());
                      index.incrementAndGet();
                      index.notify();
                      index.wait();
                    } catch (InterruptedException e) {
                      e.printStackTrace();
                    }
                }
            }
        }
    }
}
GreenGiant
  • 4,930
  • 1
  • 46
  • 76
Mosa
  • 373
  • 1
  • 14