zoukankan      html  css  js  c++  java
  • 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());
        }
    }

    【运行结果】

  • 相关阅读:
    二叉树遍历
    NO.35 2021/12/13(06:50)[周一]
    NO.29 2021/11/30(06:30)[周二]
    NO.22 2021/11/19(06:15) [周五]
    The .NET ORM Architec
    C#格式字符串
    C# Attribute
    .net DLL反编译文件
    【Beta】Scrum meeting1
    【Alpha】Scrum meeting 6
  • 原文地址:https://www.cnblogs.com/HigginCui/p/5902994.html
Copyright © 2011-2022 走看看