线程之间的通信
作者:互联网
主要是三个方法wait(); notify(); notifyAll()
wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关键字使用,即,一般在synchronized 同步代码块里使用 wait()、notify/notifyAll() 方法。
wait方法释放锁, notify方法不释放锁
由于 wait()、notify/notifyAll() 在synchronized 代码块执行,说明当前线程一定是获取了锁的。 当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。 只有当 notify/notifyAll() 被执行时候,才会唤醒一个或多个正处于等待状态的线程,然后继续往下执行,直到执行完synchronized 代码块的代码或是中途遇到wait() ,再次释放锁。 notify方法只唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。notifyAll 会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现。 wait(), notify(), notifyAll() 必须是同一对象的多个线程之间的通信 举例 Target11 public class Target1 implements Runnable { 2 3 private Demo3 demo; 4 5 public Target1(Demo3 demo) { 6 this.demo = demo; 7 } 8 9 @Override 10 public void run() { 11 demo.set(); 12 } 13 14 }
Target2
1 public class Target2 implements Runnable { 2 3 private Demo3 demo; 4 5 public Target2(Demo3 demo) { 6 this.demo = demo; 7 } 8 9 @Override 10 public void run() { 11 demo.get(); 12 } 13 14 }
Demo3
public class Demo3 { private volatile int signal; public synchronized void set () { signal = 1; notifyAll(); // notify方法会随机叫醒一个处于wait状态的线程 // notifyAll叫醒所有的处于wait线程,争夺到时间片的线程只有一个 System.out.println("叫醒线程叫醒之后休眠开始..."); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public synchronized int get () { System.out.println(Thread.currentThread().getName() + " 方法执行了..."); if(signal != 1) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + " 方法执行完毕..."); return signal; } public static void main(String[] args) { Demo3 d = new Demo3(); Target1 t1 = new Target1(d); Target2 t2 = new Target2(d); new Thread(t2).start(); new Thread(t2).start(); new Thread(t2).start(); new Thread(t2).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(t1).start(); } }
Console
hread-0 方法执行了...
Thread-2 方法执行了...
Thread-1 方法执行了...
Thread-3 方法执行了...
叫醒线程叫醒之后休眠开始...
Thread-3 方法执行完毕...
Thread-1 方法执行完毕...
Thread-2 方法执行完毕...
Thread-0 方法执行完毕...
生产者和消费者问题
Tmall
1 public class Tmall { 2 private int count; 3 4 public final int MAX_COUNT = 10; 5 6 public synchronized void push(){ 7 while (count >= MAX_COUNT){ 8 try { 9 System.out.println(Thread.currentThread().getName()+"生产者库存数量库存满,生产者停止生产"); 10 wait(); 11 } catch (InterruptedException e) { 12 e.printStackTrace(); 13 } 14 } 15 count++; 16 System.out.println(Thread.currentThread().getName()+"生产者生产,当前库存为:"+count); 17 notifyAll(); 18 } 19 20 21 22 public synchronized void take(){ 23 while (count<= 0){ 24 try { 25 System.out.println(Thread.currentThread().getName()+"生产者库存数量库0,消费者等待"); 26 wait(); 27 } catch (InterruptedException e) { 28 e.printStackTrace(); 29 } 30 } 31 32 count--; 33 System.out.println(Thread.currentThread().getName()+"生产者消费,当前库存为:"+count); 34 notifyAll(); 35 36 }
TakeTarget
1 public class TakeTarget implements Runnable{ 2 3 private Tmall tmall; 4 5 public TakeTarget(Tmall tmall){ 6 this.tmall = tmall; 7 } 8 9 10 @Override 11 public void run() { 12 13 while (true){ 14 tmall.take(); 15 try { 16 Thread.sleep(1000); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 } 21 22 } 23 }
PushTarget
1 public class PushTarget implements Runnable{ 2 3 private Tmall tmall; 4 5 public PushTarget(Tmall tmall){ 6 this.tmall = tmall; 7 } 8 9 10 @Override 11 public void run() { 12 while (true){ 13 tmall.push(); 14 try { 15 Thread.sleep(1000); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 } 20 } 21 }
Main
public static void main(String[] args) { Tmall tmall = new Tmall(); PushTarget p = new PushTarget(tmall); TakeTarget t = new TakeTarget(tmall); new Thread(p).start(); new Thread(p).start(); new Thread(p).start(); new Thread(p).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } }
生产者线程多余消费者线程
Console
Thread-6生产者消费,当前库存为:9
Thread-0生产者生产,当前库存为:10
Thread-1生产者库存数量库存满,生产者停止生产..................
完
标签:...,Thread,tmall,通信,线程,之间,new,public 来源: https://www.cnblogs.com/quyangyang/p/11184215.html