package communication; /* 使用两个线程1,2交替打印1-100 线程通信方法: 1.wait():一旦执行此方法,当前线程进入阻塞态,并释放锁 2.notify():会唤醒被wait的一个线程,如果有多个线程wait,则唤醒优先级高的 3.notifyAll():唤醒所有被wait的线程 说明: 1.wait(),notify(),notifyAll()使用在同步代码块或同步方法中,不能用在lock方法中 2.这三个方法的调用者必须是同步代码块或同步方法中的锁对象(同步监视器) 否则会出现异常 3.这三个方法定义在java.lang.Object 中 sleep()和wait()的不同 1.声明位置不同,Thread类汇总声明sleep,Object中声明wait 2.sleep可以在任何需要场景调用,wait必须由同步监视器调用 3.sleep后线程不释放锁,wait线程释放锁 @author zsben @create 2020-01-05 12:05 */ import java.util.concurrent.locks.ReentrantLock; class Number implements Runnable{ private int number = 100; private ReentrantLock lock = new ReentrantLock(false); @Override public void run() { while(true){ synchronized (this){ //唤醒所有线程线程 notifyAll(); if(number > 0){ try { //线程会阻塞,但是不会释放锁对象 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } try { //使该线程进入阻塞态,同时释放持有的锁对象 wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+": "+number); number--; }else break; } } } } public class CommunicationTest { public static void main(String[] args) { Number number = new Number(); Thread t1 = new Thread(number); Thread t2 = new Thread(number); Thread t3 = new Thread(number); t1.start(); t2.start(); t3.start(); } }
下面是生产者消费者的例子
package communication; /* 生产者消费者问题实现 @author zsben @create 2020-01-05 13:55 */ class Clerk{ private int productCount = 0; //生产产品:原子操作 public synchronized void produceProduct() { if(productCount < 20){ productCount++; System.out.println(Thread.currentThread().getName()+"生产产品"+productCount); notify(); } else { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } //消费产品:原子操作 public synchronized void consumerProduct() { if(productCount > 0){ System.out.println(Thread.currentThread().getName()+"消费产品"+productCount); productCount--; notify(); } else { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Producer extends Thread{ private Clerk clerk; public Producer(Clerk clerk) {//生产者 this.clerk = clerk; } @Override public void run() { System.out.println(getName()+": 开始生产产品..."); while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } clerk.produceProduct(); } } } class Consumer extends Thread{//消费者 private Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } @Override public void run() { System.out.println(getName()+": 开始消费产品..."); while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } clerk.consumerProduct(); } } } public class ProductTest { public static void main(String[] args) { Clerk clerk = new Clerk(); Producer p1 = new Producer(clerk); p1.setName("生产者1"); Consumer c1 = new Consumer(clerk); c1.setName("消费者1"); p1.start(); c1.start(); } }