美文网首页
Concurrency:wait及notify(All)总结

Concurrency:wait及notify(All)总结

作者: CalmHeart | 来源:发表于2019-06-23 15:32 被阅读0次

关于wait及notify、notifyAll方法的总结:

  1. 当调用wait时候,首先需要确保调用了wait方法的线程已经持有了对象的锁。
  2. 当调用了wait后,该线程会释放掉对象的锁,然后进入到等待状态(wait set)。
  3. 当线程调用了wait方法后进入等待状态时,它就可以等待其他线程调用相同对象的notify或者notifyAll方法来使得自己被唤醒。
  4. 一旦这个线程被其他线程唤醒后, 该线程就会同其他线程一同竞争这个对象的锁(公平竞争),只有当该线程获取到了这个对象的锁后,线程才会继续向下进行。
  5. 调用wait方法的片段需要放在一个synchronized块或者是synchronized方法中,这样才可以确保线程在调用wait方法前已经获取到了对象的锁。
    6.当调用对象的notify方法时,会随机唤醒等待集合(wait set)中的任意一个线程,当某个线程被唤醒后,它就会与其他线程一同竞争对象的锁。
    7.当调用notifyAll方法时,它就会唤醒该对象等待集合(wait set)中的线程,这些线程被唤醒后又开始竞争对象的锁。
    8.在某一时刻只有唯一一个线程可以拥有对象的锁。

编写一个多线程程序,实现这样一个目标:(多线程通信)

  1. 存在一个对象,该对象有一个int类型的成员变量counter 对象的初始值为0;
  2. 创建两个线程,其中一个线程对该对象的counter增加1,另一个减少1
  3. 输出该对象的counter每次变化的值。
  4. 最终输出结果是10101010101...
    IncrAndDecr.java
package com.compass.spring_lecture.thread;

public class IncrAndDecr {
  int counter;
  public synchronized void increment() {
    while (counter == 1) {
      try {
        wait();//通常wait必须放在while loop中 防止伪唤醒
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    counter++;
    System.out.print(counter);
    notify();
  }

  public synchronized void decrement() {
    while (counter == 0) {
      try {
        wait();//通常wait必须放在while loop中 防止伪唤醒
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    counter--;
    System.out.print(counter);
    notify();
  }
}

IncrThread .java

package com.compass.spring_lecture.thread;

public class IncrThread extends Thread {
  private IncrAndDecr incrAndDecr;
  public IncrThread(IncrAndDecr incrAndDecr) {
    this.incrAndDecr = incrAndDecr;
  }
  @Override
  public void run() {
    for (int i = 0; i < 30; i++) {
      try {
        Thread.sleep((long) Math.random() * 1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      incrAndDecr.increment();
    }
  }
}

DecrThread.java

package com.compass.spring_lecture.thread;
public class DecrThread extends Thread {
  private IncrAndDecr incrAndDecr;
  public DecrThread(IncrAndDecr incrAndDecr) {
    this.incrAndDecr = incrAndDecr;
  }


  @Override
  public void run() {
    for (int i = 0; i < 30; i++) {
      try {
        Thread.sleep((long) Math.random() * 1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      incrAndDecr.decrement();
    }
  }
}

MyTest2.java

package com.compass.spring_lecture.thread;

public class MyTest2 {
  public static void main(String[] args) {
    IncrAndDecr incrAndDecr = new IncrAndDecr();
    IncrThread incrThread = new IncrThread(incrAndDecr);
    DecrThread decrThread = new DecrThread(incrAndDecr);
    incrThread.start();
    decrThread.start();
  }
}

output:101010101010101010101010101010101010101010101010101010101010

相关文章

网友评论

      本文标题:Concurrency:wait及notify(All)总结

      本文链接:https://www.haomeiwen.com/subject/bejiqctx.html