zoukankan      html  css  js  c++  java
  • 并发编程(六)Object类中线程相关的方法详解

    一、notify()

    作用:唤醒一个正在等待该线程的锁的线程

    PS : 唤醒的线程不会立即执行,它会与其他线程一起,争夺资源

    /**
     * Object类的notify()和notifyAll()方法详解
     */
    public class MyNotify {
    
        // 在多线程间共享的对象上使用wait
        private String[] shareObj = {"true"};
    
        public static void main(String[] args) {
            MyNotify test = new MyNotify();
            //创建3个等待线程
            ThreadWait threadWait1 = test.new ThreadWait("线程1");
            ThreadWait threadWait2 = test.new ThreadWait("线程2");
            ThreadWait threadWait3 = test.new ThreadWait("线程3");
            //创建一个解放线程对象,用于通知等待线程运行
            ThreadNotify threadNotify = test.new ThreadNotify("释放线程");
    
            //等待线程启动,在释放线程把锁释放之后,争夺运行的机会
            threadWait1.start();
            threadWait2.start();
            threadWait3.start();
    
            //释放线程启动,sleep3秒后释放线程
            threadNotify.start();
        }
    
        /**
         * 线程等待类
         */
        class ThreadWait extends Thread {
    
            //调用父类构造方法设置线程名称
            public ThreadWait(String name) {
                super(name);
            }
    
            public void run() {
                synchronized (shareObj) {
                    while ("true".equals(shareObj[0])) {
                        System.out.println("线程" + this.getName() + "开始等待");
                        long startTime = System.currentTimeMillis();
                        try {
                            shareObj.wait();//无尽等待,直至notify()或者notifyAll()
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        long endTime = System.currentTimeMillis();
                        System.out.println("线程" + this.getName()
                                + "等待时间为:" + (endTime - startTime));
                    }
                }
                System.out.println("线程" + getName() + "等待结束");
            }
        }
    
        /**
         * 线程释放类
         */
        class ThreadNotify extends Thread {
    
            //调用父类构造方法设置线程名称
            public ThreadNotify(String name) {
                super(name);
            }
    
            public void run() {
                try {
                    // 给等待线程等待时间
                    sleep(3000);//此时sleep方法会获取对象锁,其他线程处于等待并获取锁的状态
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (shareObj) {
                    System.out.println(this.getName() + "开始准备通知");
                    shareObj[0] = "false";
                    shareObj.notify();//解放一个正在等待的线程(随机)
    //                shareObj.notifyAll();//解放所有等待的线程
                    System.out.println(this.getName() + "通知结束");
                }
                System.out.println(this.getName() + "运行结束");
            }
        }
    }

    详见这里~

    二、notifyAll()

    作用:唤醒所有正在等待该线程的锁的线程

    PS:并不一定会按线程优先级来执行

    三、wait()

    作用:导致当前的线程进入无尽等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法

    四、wait(long timeout)

    作用:导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。

    五、wait(long timeout, int nanos)

    作用:类似于wait(long timeout)方法,更精准,附加时间在毫微秒范围0-999999。

    六、常见异常

    • IllegalArgumentException -- 如果超时的值是负的或毫微秒的值不在0-999999范围内。
    • IllegalMonitorStateException -- 如果当前线程不是对象监视器的拥有者。
    • InterruptedException -- 如果另一个线程中断了当前线程。当这种异常被抛出当前线程的中断状态被清除。
  • 相关阅读:
    Golang :索引值对的数组
    MySql-BlackHole:黑洞引擎
    golang fmt 中的 Sprintf、Fprintf和 Printf函数
    golang 中的 rune 和 byte
    mysql 全文索引
    Python 原始字符串
    如何给博客园(或者CSDN)设置域名访问
    CPU、内存、磁盘三者的关系
    018.redis 阶段性总结:1T 以上海量数据+10 万以上 QPS 高并发+ 99.99% 高可用
    017.redis 在实践中的一些常见问题以及优化思路(包含 linux 内核参数优化)
  • 原文地址:https://www.cnblogs.com/riches/p/11990383.html
Copyright © 2011-2022 走看看