多线程--线程间通信
对同一个资源进行处理,但是任务却不同
线程间通信--等待唤醒机制
1、wait(); 线程处于冻结状态,被wait线程存储在线程池中
2、notify(); 从线程池唤醒一个线程
3、notifyAll(); 唤醒所有线程
方法必须定义在同步中
为什么操作线程的方法wait notify notifyAll定义在Object类中
因为这些方法是监视器的方法,监视器其实就是锁
锁可以是任意的对象,任意的对象调用的方式一定是定义在Object类中
唤醒--代码优化
多生产者多消费者
多生产多消费者问题解决
notifyAll();
while判断标记,解决了线程获取执行权后是否重新运行
notifyAll()解决了本方线程一定唤醒对方线程
多生产多消费问题 JDK1.5新特性 -- Lock
同步代码块,对于锁的操作是隐式的。
1 import java.util.concurrent.locks.*; 2 //import java.util.condition; 3 class Resource{ 4 private String name; 5 private int count = 1; 6 private boolean flag = false; 7 Lock lock = new ReentrantLock(); 8 //Condition c1 = lock.newCondition(); 9 Condition pro_con = lock.newCondition(); 10 Condition cos_con = lock.newCondition(); 11 12 Resource(){} 13 14 public void set(String name){//synchronized 15 lock.lock(); 16 try{ 17 while(flag)//while(flag)--死锁 18 //try{wait();}catch(InterruptedException e){} 19 try{pro_con.await();}catch(InterruptedException e){} 20 this.name = name + count; 21 count++; 22 System.out.println(Thread.currentThread().getName()+": 生产..5.0. "+this.name); 23 flag = true; 24 //notifyAll();//notifyAll() 25 //c1.signalAll();//notifyAll() 26 cos_con.signal();//notifyAll() 27 } 28 finally{ 29 lock.unlock(); 30 } 31 32 33 } 34 35 public void out(){ //synchronized 36 lock.lock(); 37 try{ 38 while(!flag)//while(flag)--出现死锁--notifyAll() 39 try{cos_con.await();}catch(InterruptedException e){} 40 System.out.println(Thread.currentThread().getName()+":...消费了......"+name); 41 flag = false; 42 //notifyAll();//notifyAll()} 43 //c1.signalAll(); 44 pro_con.signal(); 45 46 } 47 finally{ 48 lock.unlock();//notifyAll() 49 } 50 } 51 } 52 53 class Producer implements Runnable{ 54 private Resource r; 55 Producer(Resource r){ 56 this.r = r; 57 } 58 59 public void run(){ 60 while(true){ 61 r.set("烤鸭"); 62 } 63 64 } 65 } 66 67 class Consumer implements Runnable{ 68 private Resource r; 69 Consumer(Resource r){ 70 this.r = r; 71 } 72 public void run(){ 73 while(true){ 74 r.out(); 75 } 76 } 77 } 78 79 class ProduceConsumerDemo{ 80 public static void main(String[] args){ 81 Resource r = new Resource(); 82 Producer pro = new Producer(r); 83 Consumer con = new Consumer(r); 84 85 Thread t0 = new Thread(pro); 86 Thread t1 = new Thread(pro); 87 Thread t2 = new Thread(con); 88 Thread t3 = new Thread(con); 89 90 t0.start(); 91 t1.start(); 92 t2.start(); 93 t3.start(); 94 95 } 96 }
将同步和锁封装成了对象
JDK1.5新特性--condition
wait notify notifyAll
JDK1.5解决方法
一个锁多个监视器
范例
Lock 接口:替代了同步代码块或同步函数,由隐式锁操作变成显示
lock() 获取锁
unlock() 释放锁 在finally代码块中
Condition 接口 替代了Object中的wait notify notifyAll方法,单独进行封装
await
signal
signalAll
1 class BoundedBuffer { 2 final Lock lock = new ReentrantLock(); 3 final Condition notFull = lock.newCondition(); 4 final Condition notEmpty = lock.newCondition(); 5 6 final Object[] items = new Object[100]; 7 int putptr, takeptr, count; 8 9 public void put(Object x) throws InterruptedException { 10 lock.lock(); 11 try { 12 while (count == items.length) 13 notFull.await(); 14 items[putptr] = x; 15 if (++putptr == items.length) putptr = 0; 16 ++count; 17 notEmpty.signal(); 18 } finally { 19 lock.unlock(); 20 } 21 } 22 23 public Object take() throws InterruptedException { 24 lock.lock(); 25 try { 26 while (count == 0) 27 notEmpty.await(); 28 Object x = items[takeptr]; 29 if (++takeptr == items.length) takeptr = 0; 30 --count; 31 notFull.signal(); 32 return x; 33 } finally { 34 lock.unlock(); 35 } 36 } 37 }
wait sleep 区别
1、wait可以指定时间也可以不指定,sleep必须指定
2、在同步中,对cpu的执行权和锁的处理不同
wait 释放执行权和锁
sleep 释放执行权 不是释放锁
停止线程方式--定义标记
1、stop方法
2、run方法结束
怎么控制线程的任务结束呢?
控制循环就可以结束任务
停止线程方式--Interrupt
如果线程处于冻结状态,无法读取标记,如何结束?
interrupt 将线程从冻结强制恢复成运行状态,但会发生中断异常
守护进程--setDaemon
后台线程,先于线程启动前调用
join方法
setPriority(Thread.MAX_PRIORITY)
yield