Java Day 14

多线程--线程间通信
 对同一个资源进行处理,但是任务却不同

线程间通信--等待唤醒机制
 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 }
View Code


 将同步和锁封装成了对象

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  }
View Code

wait sleep 区别
 1、wait可以指定时间也可以不指定,sleep必须指定
 2、在同步中,对cpu的执行权和锁的处理不同
    wait 释放执行权和锁
    sleep 释放执行权 不是释放锁

停止线程方式--定义标记
 1、stop方法
 2、run方法结束
 怎么控制线程的任务结束呢?
  控制循环就可以结束任务

停止线程方式--Interrupt
 如果线程处于冻结状态,无法读取标记,如何结束?
 interrupt 将线程从冻结强制恢复成运行状态,但会发生中断异常

守护进程--setDaemon
 后台线程,先于线程启动前调用

join方法
 setPriority(Thread.MAX_PRIORITY)
 
 yield

原文地址:https://www.cnblogs.com/zhuzhuqwa/p/5922075.html