• 线程通信之初认识


     1 package day2_4;
     2 
     3 /**
     4  * 线程通信:线程1和线程2,轮流交替打印1-100
     5  *
     6  * 涉及到的三个方法:
     7  * wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器
     8  * notify():一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程被wait,就唤醒优先级高的那个
     9  * notifyAll():一旦执行此方法,就会唤醒所有的被wait的线程
    10  *
    11  * 说明:
    12  * 1.上面三个方法必须使用在同步代码块或者同步方法中
    13  * 2.上面三个方法的调用者必须是同步代码块或者同步方法中的同步监视器
    14  *      否则会出现IllegalMonitorStateException  ---非法监视器异常
    15  * 3.上面三个方法是定义在java.lang.Object类中,因为任何类都是Object的子类,所以任何类的对象都可以充当
    16  *   同步监视器,并且调动上面三个方法。
    17  *
    18  * 面试题:sleep() 和 wait() 的异同?
    19  * 相同点:一旦执行方法,都可以使当前线程进入阻塞状态
    20  * 不同点:1)方法声明的位置不同:sleep()声明在Thread类中,wait()声明在Object类中
    21  *        2)调用的要求不同:sleep()可以在任何需要的场景调用,wait()必须在同步代码块或
    22  *          同步方法中才能调用
    23  *        3)关于是否释放同步监视器(锁):如果两个方法都使用在同步代码块或者同步方法中,sleep()不会释放锁,
    24  *          而wait()会释放锁。
    25  *
    26  *
    27  * @Author Tianhao
    28  * @create 2021-02-05-21:05
    29  */
    30 
    31 class Number implements Runnable{
    32     private int number = 1;
    33     private Object obj = new Object();
    34 
    35 //    //这是原本的打印情况
    36 //    @Override
    37 //    public void run() {
    38 //        while (true) {
    39 //            //这里加入sleep,是为了更好地看到两个线程交替打印的现象
    40 //            try {
    41 //                Thread.sleep(5);
    42 //            } catch (InterruptedException e) {
    43 //                e.printStackTrace();
    44 //            }
    45 //            synchronized (this) {
    46 //                if (number <= 100) {
    47 //                    System.out.println(Thread.currentThread().getName() + "打印:" + number);
    48 //                    number++;
    49 //                } else {
    50 //                    break;
    51 //                }
    52 //            }
    53 //        }
    54 //    }
    55 
    56     //利用线程通信,实现两个线程轮流交替打印
    57     @Override
    58     public void run() {
    59         while (true) {
    60             //当同步监视器是Object对象obj时,wait()、notify()、notifyAll()的调用者也必须是obj
    61             //synchronized (obj) {
    62             synchronized (this) {
    63                 //2.notify()唤醒正在wait的线程
    64                 //obj.notify();
    65                 notify(); //因为此时同步监视器是this,所以可以省略this.
    66                 if (number <= 100) {
    67                     System.out.println(Thread.currentThread().getName() + "打印:" + number);
    68                     number++;
    69                 } else {
    70                     break;
    71                 }
    72                 try {
    73                     //1.线程一旦执行wait(),就会阻塞,同时释放同步监视器
    74                     //obj.wait();
    75                     wait(); //因为此时同步监视器是this,所以可以省略this.
    76                 } catch (InterruptedException e) {
    77                     e.printStackTrace();
    78                 }
    79             }
    80         }
    81     }
    82 }
    83 
    84 public class CommunityTest {
    85     public static void main(String[] args) {
    86         Number n = new Number();
    87         Thread t1 = new Thread(n);
    88         Thread t2 = new Thread(n);
    89         t1.setName("线程1");
    90         t2.setName("线程2");
    91         t1.start();
    92         t2.start();
    93     }
    94 }
  • 相关阅读:
    视频高清直播RTMP视频推流组件EasyRTMP-IOS版如何使用wchar_t*类型参数?
    设计模式
    算法学习【第10篇】:算法之动态规划问题
    算法学习【第9篇】:算法之斐波那契数列
    算法学习【第8篇】:贪心算法找零问题
    算法学习【第7篇】:算法之迷宫问题
    算法学习【第6篇】:算法之数据结构
    算法学习【第5篇】:常用排序算法(*******)
    算法学习【第4篇】:算法之---堆的简单介绍
    算法学习【第3篇】:树和二叉树简介
  • 原文地址:https://www.cnblogs.com/zui-ai-java/p/14380265.html
Copyright © 2020-2023  润新知