Java Day 14

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

线程间通信--等待唤醒机制
 1、wait();   线程处于冻结状态,被wait线程存储在线程池中
 2、notify(); 从线程池唤醒一个线程
 3、notifyAll(); 唤醒所有线程
 方法必须定义在同步中

为什么操作线程的方法wait notify notifyAll定义在Object类中
  因为这些方法是监视器的方法,监视器其实就是锁
  锁可以是任意的对象,任意的对象调用的方式一定是定义在Object类中

唤醒--代码优化

多生产者多消费者
 
多生产多消费者问题解决
 notifyAll();
 
 while判断标记,解决了线程获取执行权后是否重新运行
 
 notifyAll()解决了本方线程一定唤醒对方线程

多生产多消费问题 JDK1.5新特性 -- Lock
 同步代码块,对于锁的操作是隐式的。

 import java.util.concurrent.locks.*;
//import java.util.condition;
class Resource{
private String name;
private int count = 1;
private boolean flag = false;
Lock lock = new ReentrantLock();
//Condition c1 = lock.newCondition();
Condition pro_con = lock.newCondition();
Condition cos_con = lock.newCondition(); Resource(){} public void set(String name){//synchronized
lock.lock();
try{
while(flag)//while(flag)--死锁
//try{wait();}catch(InterruptedException e){}
try{pro_con.await();}catch(InterruptedException e){}
this.name = name + count;
count++;
System.out.println(Thread.currentThread().getName()+": 生产..5.0. "+this.name);
flag = true;
//notifyAll();//notifyAll()
//c1.signalAll();//notifyAll()
cos_con.signal();//notifyAll()
}
finally{
lock.unlock();
} } public void out(){ //synchronized
lock.lock();
try{
while(!flag)//while(flag)--出现死锁--notifyAll()
try{cos_con.await();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+":...消费了......"+name);
flag = false;
//notifyAll();//notifyAll()}
//c1.signalAll();
pro_con.signal(); }
finally{
lock.unlock();//notifyAll()
}
}
} class Producer implements Runnable{
private Resource r;
Producer(Resource r){
this.r = r;
} public void run(){
while(true){
r.set("烤鸭");
} }
} class Consumer implements Runnable{
private Resource r;
Consumer(Resource r){
this.r = r;
}
public void run(){
while(true){
r.out();
}
}
} class ProduceConsumerDemo{
public static void main(String[] args){
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r); Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t3 = new Thread(con); t0.start();
t1.start();
t2.start();
t3.start(); }
}

将同步和锁封装成了对象

JDK1.5新特性--condition
 wait notify notifyAll

JDK1.5解决方法
 一个锁多个监视器

范例
 Lock 接口:替代了同步代码块或同步函数,由隐式锁操作变成显示
  lock()   获取锁
  unlock() 释放锁 在finally代码块中

Condition 接口 替代了Object中的wait notify notifyAll方法,单独进行封装
  await
  signal
  signalAll

  class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100];
int putptr, takeptr, count; public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
} public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}

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

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

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

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

join方法
 setPriority(Thread.MAX_PRIORITY)
 
 yield

上一篇:JAVA8之Lambda表达式与方法引用表达式


下一篇:java8 探讨与分析匿名内部类、lambda表达式、方法引用的底层实现