java - Beberapa keraguan tentang notify()/wait()
PHP中文网
PHP中文网 2017-05-17 09:58:07
0
1
712
class MyObject{
    private Queue<String> queue = new ConcurrentLinkedQueue<String>();
    public synchronized void set(String s){
            while(queue.size() >= 10){
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            queue.add(s);
            notify();
    }
}

class Producer implements Runnable{
    private MyObject myObj;
    
    public Producer(MyObject myObj) {
        this.myObj= myObj;
    }

    @Override
    public void run() {
        // 每条线程执行30次set
        for (int i = 0; i < 30; i++) {
            this.myObj.set("obj:" + i);
        }
    }
}

public static void main(String[] args){
    Producer producer = new Producer(new MyObject());
        
    // 生成30条线程
    for (int i = 0; i < 10; i++) {
        Thread thread = new Thread(producer);
        thread.start();
    }
    // 运行结果是只set了30次
}

Ragu saya ialah apabila notify() menerbitkan pemberitahuan, mengapa ia tidak membiarkan kaedah wait() thread lain terus dilaksanakan?

PHP中文网
PHP中文网

认证高级PHP讲师

membalas semua(1)
習慣沉默

Apabila bilangan baris gilir anda melebihi 10, setiap utas anda akan bermula wait()住了, 不会走到notify()的啊. 你需要一个单独的线程去监控队列的大小, 大于10的时候notify() dahulu, anda boleh menukar sedikit

class MyObject {
    private Queue<String> queue = new ConcurrentLinkedQueue<String>();

    private volatile int limit = 10;

    public synchronized void set(String s) {
      if (queue.size() >= limit) {
        try {
          wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      queue.add(s);
    }

    public synchronized void delta() {
      if (queue.size() >= limit) {
        limit += 10;
        notify();
      }
    }
}

Kemudian ada benang pemantauan

class Monitor implements Runnable {

    private MyObject myObj;

    public Monitor(MyObject myObj) {
      this.myObj = myObj;
    }

    @Override
    public void run() {
      while (true) {
        myObj.delta();
      }
    }
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan