首页 > 其他分享 >线程中wait的用法

线程中wait的用法

时间:2022-12-27 16:57:28浏览次数:33  
标签:thread resourceA 用法 nanos 线程 timeout wait

线程中wait的用法

Thread thread_d = new Thread(() -> {
            synchronized (resourceA) {
                System.out.println("thread_d get resourceA Lock");
                for (int i = 0; i < 100; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(i==5) {
                        try {
                            //让该线程等待阻塞 5 秒中后重新获取锁对象
                            resourceA.wait(1000*5);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("thread_d ===> " + i);
                }
            }
        }, "thread_d");

        Thread thread_e = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (resourceA) {
                System.out.println("tread_e get resourceA Lock");
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(i==6){
                        try {
                            resourceA.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("thread_e ===> " + i);
                }
            }
        }, " thread_e");

如果启动上面两个线程会发生什么现象呢?

首先线程 thread_d 启动,1秒钟后线程 thread_e 启动,并且线程 thread_d 优先获取锁共享变量锁 resourceA ,在 5 秒中后,线程 thread_d 释放锁资源处于阻塞状态,线程 thread_e 获得锁资源,在 5 秒中后,线程 thread_b 释放锁资源,同时进入阻塞状态。此时线程 thread_d 已经被唤醒处于就绪状态,等待抢夺 thread_b 释放的 共享变量锁 resourceA ,当 thread_d 重新抢夺获取资源后,线程 thread_d 重新进入运行状态。

关于 wait 的几种方法

    public final void wait() throws InterruptedException {
        wait(0);
    }
    public final native void wait(long timeout) throws InterruptedException;
    public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) {
            timeout++;
        }

        wait(timeout);
    }

比较有意思的是 wait(long timeout ,int nanos) 这个方法

官方给出的解释是,为了更加精准的控制并发的时间后面的 参数 nanos 只要 满足大于 0 并且小于 999999 这个条件,(1毫秒 = 1000 微秒 = 1000 000 纳秒)就在原先的等待时间上加 1 毫秒。

早起的 jdk 中关于 wait(long timeout ,int nanos) 方法

public final void wait(long timeout, int nanos) throws nterruptedException {
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }
    // nanos 单位为纳秒,  1毫秒 = 1000 微秒 = 1000 000 纳秒
    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                "nanosecond timeout value out of range");
    }

    // nanos 大于 500000 即半毫秒  就timout 加1毫秒
    // 特殊情况下: 如果timeout为0且nanos大于0,则timout加1毫秒
    if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
        timeout++;
    }

    wait(timeout);
}

【思考】

其实个人感觉,这里的 nanos 其实很没有意思,就目前常用的 1.8 JDK 中 wait 方法 nanos 参数的判断范围为(0-999999),那么只要传入的参数值在这个范围内,原先的延时时间都是加 1 毫秒,这就显得 nanos 这个参数无任何实质性的意义了。

标签:thread,resourceA,用法,nanos,线程,timeout,wait
From: https://www.cnblogs.com/peggys/p/17008424.html

相关文章

  • 多线程基础
    并发和并行的概念有了解?Java实现并发的方式有几种?线程和进程的概念?守护线程是干什么的?常见的守护线程有哪些?Java怎么创建一个线程,native关键字的作用是什么?Thread类中绝......
  • 详解JAVA线程问题诊断工具Thread Dump
    摘要:ThreadDump是非常有用的诊断Java应用问题的工具。本文分享自华为云社区《调试排错-Java线程分析之线程Dump分析》,作者:龙哥手记。ThreadDump是非常有用的诊断Jav......
  • 异步编排多线程任务事务控制
    /***<p>*<B>Description:异步编排多线程任务事务控制</B>*</P>*RevisionTrail:(Date/Author/Description)*2022/12/26RyanHuangCREATE*多线程异步......
  • WinHttp用法
    示例#include<string>#include<iostream>#include<windows.h>#include<winhttp.h>#pragmacomment(lib,"winhttp.lib")#pragmacomment(lib,"user32.lib")vo......
  • 趣站|最佳ChatGPT示例用法-LearnGPT
    趣站,专注于收藏国内外最好玩有趣有意思的趣站和酷站。收藏全球最有趣的网站。网站简介LearnGPT,一个专门收集展示最佳ChatGPT示例用法的国外网站,ChatGPT示例用法涉及各种行业......
  • Java线程中的wait、notify和notifyAll解析
    等待唤醒案例:线程间的通信顾客去包子铺买包子,告知老板自身需求后,进入等待(调用wait()方法)老板处理的过程,此时顾客的状态为WAITING,老板做好包子后,告知(调用notify()方法)顾......
  • 线程池的概念和使用
    线程池思想概述我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样......
  • POSIX 多线程程序设计
     POSIX 多线程程序设计 目录表 ​​摘要​​  ​​译者序​​​Pthreads概述 ​​​什么是线程? ​​​​什么是Pthreads? ​​​​为什么使用Pthreads? ​......
  • python进程之进程池、线程池与异步回调机制
    fromconcurrent.futuresimportProcessPoolExecutor,ThreadPoolExecutorimportosimporttimeimportrandom#1.产生含有固定数量线程的线程池#t_pool=Thread......
  • Windows操作系统TIME_WAIT状态的TCP连接快速回收时间(性能测试时端口不够用)
    https://www.bilibili.com/read/cv16258140大规模Windows环境下,采用Nginx反向代理服务后,操作系统会产生较多TIME_WAIT的TCP(TransmissionControlProtocol)连接,操作系统......