zoukankan      html  css  js  c++  java
  • JAVA多线程(八):线程通信(一)线程的通信基础

    1 通信方法

    1.1 wait() 与 notify() 和 notifyAll()

      wait():令当前线程挂起并放弃CPU、同步资源并等待,使别的线程可访问并修改共享资源,而当前线程排队等候其他线程调用notify()或notifyAll()方法唤醒,唤醒后等待重新获得对监视器的所有权后才能继续执行。
      notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
      notifyAll ():唤醒正在排队等待资源的所有线程结束等待.
    这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则会报java.lang.IllegalMonitorStateException异常。
    因为这三个方法必须有锁对象调用,而任意对象都可以作为synchronized的同步锁,因此这三个方法只能在Object类中声明。

    1.2  wait() 方法

    在当前线程中调用方法: 对象名.wait()
    使当前线程进入等待(某对象)状态 ,直到另一线程对该对象发出 notify(或notifyAll) 为止。
    调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)
    调用此方法后,当前线程将释放对象监控权 ,然后进入等待
    在当前线程被notify后,要重新获得监控权,然后从断点处继续代码的执行。

    1.3 notify()/notifyAll()

    在当前线程中调用方法: 对象名.notify()
    功能:唤醒等待该对象监控权的一个/所有线程。
    调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)

    2 实例

    package com.atguigu.java2;
    
    /**
     * 线程通信的例子:使用两个线程打印 1-100。线程1, 线程2 交替打印
     *
     * 涉及到的三个方法:
     * wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
     * notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
     * notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。
     *
     * 说明:
     * 1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。
     * 2.wait(),notify(),notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器。
     *    否则,会出现IllegalMonitorStateException异常
     * 3.wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中。
     *
     * 面试题:sleep() 和 wait()的异同?
     * 1.相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
     * 2.不同点:1)两个方法声明的位置不同:Thread类中声明sleep() , Object类中声明wait()
     *          2)调用的要求不同:sleep()可以在任何需要的场景下调用。 wait()必须使用在同步代码块或同步方法中
     *          3)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。
     *
     * @author shkstart
     * @create 2019-02-15 下午 4:21
     */
    class Number implements Runnable{
        private int number = 1;
        private Object obj = new Object();
        @Override
        public void run() {
    
            while(true){
    
                synchronized (obj) {
    
                    obj.notify();
    
                    if(number <= 100){
    
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                        System.out.println(Thread.currentThread().getName() + ":" + number);
                        number++;
    
                        try {
                            //使得调用如下wait()方法的线程进入阻塞状态
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }else{
                        break;
                    }
                }
    
            }
    
        }
    }
    
    
    public class CommunicationTest {
        public static void main(String[] args) {
            Number number = new Number();
            Thread t1 = new Thread(number);
            Thread t2 = new Thread(number);
    
            t1.setName("线程1");
            t2.setName("线程2");
    
            t1.start();
            t2.start();
        }
    }
  • 相关阅读:
    700. Search in a Binary Search Tree
    100. Same Tree
    543. Diameter of Binary Tree
    257. Binary Tree Paths
    572. Subtree of Another Tree
    226. Invert Binary Tree
    104. Maximum Depth of Binary Tree
    1、解决sublime打开文档,出现中文乱码问题
    移植seetafaceengine-master、opencv到ARM板
    ubuntu16.04-交叉编译-SeetaFaceEngine-master
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/14232682.html
Copyright © 2011-2022 走看看