synchronize two threads in java

匿名 (未验证) 提交于 2019-12-03 08:57:35

问题:

I have two threads in my java programme, one is main thread and other thread is thread A which is spawned in main thread. now i want main thread to start thread A and wait till thread A has executed some part of its code in run method and thread A should suspend itself. main thread should then start running, run few lines of code and then again thread A should start from where it has stopped and vice versa. this should happen for n number of times. I am trying as belows:

Thread A class:

public class ThreadA implements Runnable {     boolean suspended = false;     boolean stopped = false;     synchronized void stop() {         stopped = true;         suspended = false;         notify();     }     synchronized void suspend() {         suspended = true;     }     synchronized void resume() {         suspended = false;         notify();     }     void job() throws InterruptedException {         for (int i = 0; i < 5; i++)             synchronized (this) {                 System.out.println("performing job.");                 suspend();                 while (suspended) {                     notify();                     suspended = false;                 }             }     }     @Override     public void run() {         try {             job();         } catch (InterruptedException e) {             e.printStackTrace();         }     } }

MainThread:

public class MainThread {     public static void main(String[] args) throws InterruptedException {         ThreadA a1=new ThreadA();         Thread t1=new Thread(a1);         synchronized (t1) {             t1.start();             for (int i = 0; i < 5; i++) {                 t1.wait();                 System.out.println("perform some action");                 a1.resume();             }          }     } }

Expected output:

performing job. perform some action performing job. perform some action performing job. perform some action performing job. perform some action performing job. perform some action

Actual output:

performing job. performing job. performing job. performing job. performing job. perform some action

I don't know why the whole for loop is getting executed in Thread A even when i've issued a notify() signal in job method.

回答1:

Here is more simplified way

public class TwoThread {      public static void main(String[] args) throws InterruptedException {         ThreadA a1 = new ThreadA();         Thread t1 = new Thread(a1);          synchronized (a1) {             t1.start();             for (int i = 0; i < 5; i++) {                 a1.wait();                 System.out.println("perform some action " + i);                 a1.notify();             }          }     } }  public class ThreadA implements Runnable {     boolean suspended = false;     boolean stopped = false;      void job() throws InterruptedException {         for (int i = 0; i < 5; i++)             synchronized (this) {                 System.out.println("performing job. " + i);                 notify();                 wait();             }     }      public void run() {         try {             job();         } catch (InterruptedException e) {             e.printStackTrace();         }      }  }


回答2:

You have two bugs here.

The first is that you are synchronizing and notifying different objects. Try this modified main, I changed synchronized (t1) to synchronized (a1) and t1.wait() to a1.wait().

public static void main(String[] args) throws InterruptedException {     ThreadA a1=new ThreadA();     Thread t1=new Thread(a1);      synchronized (a1) {    // CHANGED FROM t1 to a1         t1.start();         for (int i = 0; i < 5; i++) {             a1.wait();    // CHANGED FROM t1 to a1             System.out.println("perform some action");             a1.resume();         }      } }

The second bug is in the job() method, it calls notify() but not wait(). Here is a fixed version:

void job() throws InterruptedException {     for (int i = 0; i < 5; i++)         synchronized (this) {             System.out.println("performing job.");             suspend();             while (suspended) {                 notify();                 suspended = false;                 wait();    // ADDED             }         } }

The output from my test run is

performing job. perform some action performing job. perform some action performing job. perform some action performing job. perform some action performing job. perform some action


回答3:

There is little reason to synchronize multiple threads if one threads waits while another does its thing. One could use Executors to get the same result with less work and still got the feeling that one is playing with the threads.

public class Main {      public static void main(String[] args) {         ExecutorService executor = Executors.newSingleThreadExecutor();         for(int i = 0; i<5;i++) {             executor.submit(new PrintTask("performing job."));             executor.submit(new PrintTask("perform some action"));         }         executor.shutdown();     }      private static class PrintTask implements Runnable {         private String string;          public PrintTask(String string) {             this.string = string;         }          @Override         public void run() {             System.out.println(string);         }     }  }


转载请标明出处:synchronize two threads in java
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!