首页 > 代码库 > Java Day 14

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){//synchronized15         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(){ //synchronized36         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

Java Day 14