notifyall() - 在使用静态同步方法的线程上

时间:2017-08-22 17:35:25

标签: java multithreading

我有以下代码,我试图根据id 0,1,2打印线程:但由于某种原因,notifyall()不适合我,它只打印第一个线程,似乎是其他人只是在等待。

public class WorkThread extends Thread {

    private int[] vec;
    private int id;
    private int res;
    static Integer printNowId = 0;

    public WorkThread(int[] vec, int id) {
        this.vec = vec;
        this.id = id;
    }

    public  synchronized void checkTurn(int id){
        while (id != printNowId){
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public  synchronized void done(){
        printNowId = printNowId + 1 ;
        notifyAll();
    }

    public static synchronized int p(int[] vec, int id){
        int res = 0;

        for(int i=0;i<vec.length;i++){
            vec[i] = vec[i] + 1; 
            res = res +vec[i];
        }

        return res;
    }

    public  void run () {
        res = p(vec,id);
        checkTurn(id);
        System.out.println("task " + id + " res= " + res);
        done();
    }
}

公共类DriverABCD {

public static void main(String[] args) throws InterruptedException {

    int vec[] = {1,2,3,4};
    WorkThread[] workers = new WorkThread[3];
    for(int i=0;i<3;i++){
        workers[i] = new WorkThread(vec,i);
    }

    for(int i=0;i<3;i++){
        workers[i].start();
    }

    System.out.println("main");

}

仅打印第一个线程。而另一个则不是。

1 个答案:

答案 0 :(得分:0)

您使用的是错误的锁定对象。你锁定每个WorkThread,但WorkThread 0不释放WorkThread 1或2,反之亦然。

您需要的是一个锁定对象,以便所有WorkThread同步。您可以对代码进行以下更改。

public class WorkThread extends Thread {
...
   static Object lock = new Object();
...
   public void checkTurn(int id) {
     synchronized (lock) {
        while (id != printNowId) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
     }
  }

   public void done() {
     synchronized (lock) {
        printNowId = printNowId + 1;
        lock.notifyAll();
     }
   }
...

输出如下:

task 0 res= 14
main
task 1 res= 18
task 2 res= 22