• 05_线程间通信


    【简述】

    为了支持多线程之间的协作,JDK提供了两个重要的线程方法:通知notify()、等待wait()。

    任何对象都可以调用这两个方法,因为他们在Object类中。

    【wait方法】

    当一个对象调用了wait方法之后,当前线程就会在这个对象上等待。比如,线程A中,调用了obj.wait()方法,那么线程A就会停止执行,而转为等待状态,同时当前线程释放持有的锁,线程A会一直等待到其它线程调用了obj.notify()方法通知到自己位置。obj对象成为了多个线程之间通信的手段。

    【wait方法和notify方法工作细节】

         如果一个线程调用了object.wait(),那么他就会进入object对象的等待队列。这个等待队列中,可能会有多个线程,因为系统运行多个线程同时会等待某一对象,当object.notify()方法被调用后,它就会从这个等待队列中随机选择一个线程(和队列中的顺序无关),并将其唤醒。

        notifyAll()可以唤醒所有的等待线程,而不是随机选择一个。

    注意:object.wait()方法不可以随意调用,必须包含在对应的synchronizd语句中。无论是wait()还是notify()方法都需要获得目标对象的一个监听器。

    【使用wait和notify的注意点】

    1.wait和notify必须配合synchronized关键字使用

    2.wait方法释放锁,而notify不会释放锁

    【例子】

    package com.part1.sync005;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class SimpleWN {
        final static Object object = new Object();
        
        public static class T1 extends Thread{
            @Override
            public void run() {
                synchronized(object){
                    System.out.println(getNowTime()+" T1 start!!!");
                    try{
                        Thread.sleep(1000);
                        System.out.println(getNowTime()+" T1 wait for Object... ");
                        object.wait();     //T1释放锁,等待其他线程来唤醒
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    System.out.println(getNowTime()+" T1 end...");
                }
            }
        }
        
        public static class T2 extends Thread{
            @Override
            public void run() {
                synchronized(object){
                    try {
                        System.out.println(getNowTime()+" T2 start !!! notify one Thread !!!");
                        object.notify();  //从object等待队列中随机唤醒一个等待线程,此时只有T1在等待,故唤醒T1
                        System.out.println(getNowTime()+" T2 end...");  //虽然T2唤醒了T1线程,但是T2此时依然持有锁,所以T1处于阻塞状态
                        Thread.sleep(2000);   //T2执行结束,释放锁,T1方可去获取锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        public static void main(String[] args) {
            Thread t1 = new T1();
            Thread t2 = new T2();
            
            t1.start();
            t2.start();
        }
        
        public static String getNowTime(){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(new Date());
        }
    }

    【运行结果】

  • 相关阅读:
    Java异常
    Vector ArrayList LinkedList
    线程池
    Linux alias 或者 unalias 设置别名
    vim 知识点小结
    vim下出现^M怎么解决
    解决pip安装时出现报错TypeError unsupported operand type(s) for -= 'Retry' and 'int'
    MySQL备份与恢复
    mysql 去重的两种方式
    查看python的安装版本,位数及安装路径
  • 原文地址:https://www.cnblogs.com/HigginCui/p/5902994.html
Copyright © 2020-2023  润新知