• 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

  • 相关阅读:
    centos免密码登录
    conda3 快速下载python包
    Flink问题及解决方案
    git把项目推送到不同的remote(git地址)
    选择器提取内容
    spark写入mysql
    flume简介及netcat样例
    Spark 读取 Hbase 优化 --手动划分 region 提高并行数
    shell grep正则表达式
    Hibernate持久化
  • 原文地址:https://www.cnblogs.com/zhuzhuqwa/p/5922075.html
Copyright © 2020-2023  润新知