Java学习: wait和notify方法、ThreadLocal
wait方法和notift方法
其实我们之前可能就发现了,Object类还有三个方法我们从来没有使用过,分别是wait()、notify()以及notifyAll(),他们其实是需要配合synchronized来使用的,只有在同步代码块中才能使用这些方法,下面看看他们的作用是什么。
public class Main {public static void main(String[] args) throws InterruptedException {Object o1 = new Object();Thread t1 = new Thread(() -> {synchronized (o1){try{System.out.println("开始等待");o1.wait(); //等待状态并释放锁System.out.println("等待结束");}catch(InterruptedException e){e.printStackTrace();}}});Thread t2 = new Thread(() -> {synchronized (o1){System.out.println("开始唤醒");o1.notify(); //唤醒出狱等待状态的线程for (int i = 0; i < 50; i++){System.out.println(i);}}});t1.start();Thread.sleep(1000);t2.start();}
}
对象的wait()方法会暂时使得此线程进入等待状态,同时会释放当前代码块持有的锁,这是其他线程可以获取对此对象的锁,当其他线程调用对象的notify()方法后,会唤醒刚才变成等待状态的线程(这时并没有立刻释放锁)。请注意,必须是在持有锁(同步代码块内部)的情况下使用,否则会抛出异常!
notifyAll其实和notify一样,也是用于唤醒,但是前者是唤醒所有调用wait()后处于等待的线程,而后者是看运气随机选择一个。
ThreadLocal的使用
既然每个线程都有一个自己的工作内存,那么能否只在自己的工作内存中创建变量仅供线程自己使用呢?
我们可以使用ThreadLocal类,来创建工作内存中的变量,它将我们的变量值存储在内部(只能存储一个变量),不同变量的访问到ThreadLocal对象时,都只能获取到自己线程所属的变量。
实例:
public class Main {public static void main(String[] args) throws InterruptedException {ThreadLocal<String> local = new ThreadLocal<>(); //注意这是一个泛型类,存储类型为我们要存放的变量类型Thread t1 = new Thread(() -> {local.set("sjsjsj"); //将变量的值给予ThreadLocalSystem.out.println("变量值已设定");System.out.println(local.get()); //尝试获取ThreadLocal中存放的变量});Thread t2 = new Thread(() -> {System.out.println(local.get()); //尝试获取ThreadLocal中存放的变量});t1.start();Thread.sleep(1000);t2.start();}
}
上述例子中,我们开启两个线程分别访问ThreadLocal对象,第一个线程存放的内容,第一个可以获取,第二个无法获取。因此各个线程直接存放的内容互不干扰。
包括创建的子线程,也无法获得父线程工作内存中的变量。
public class Main {public static void main(String[] args) throws InterruptedException {ThreadLocal<String> local = new ThreadLocal<>(); //注意这是一个泛型类,存储类型为我们要存放的变量类型Thread t1 = new Thread(() -> {local.set("ssjj");new Thread(() -> {System.out.println(local.get());}).start();});t1.start();}
}
此时可以使用InheritableThreadLocal解决
public class Main {public static void main(String[] args) throws InterruptedException {ThreadLocal<String> local = new InheritableThreadLocal<>(); //注意这是一个泛型类,存储类型为我们要存放的变量类型Thread t1 = new Thread(() -> {local.set("ssjj");new Thread(() -> {System.out.println(local.get());}).start();});t1.start();}
}
Java学习: wait和notify方法、ThreadLocal相关推荐
- Java学习之路3——方法定义、调用【重拾Java】
Java学习之路3--方法定义.调用[重拾Java] 方法定义 为什么要写方法 方法完整的定义形式.调用 方法定义的格式 修饰符 返回值类型 返回值 调用格式 方法重载 方法定义 为什么要写方法 对于 ...
- 好程序员Java学习路线分享finalize()方法详解
好程序员Java学习路线分享finalize()方法详解,前言,finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法.. fi ...
- java学习笔记5--类的方法
接着前面的学习: java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址 ...
- java thread.notify_Java Thread notify()方法
Thread类的notify()方法用于唤醒单个线程. 此方法仅为一个等待特定对象的线程提供通知. 如果使用notify()方法并且有多个线程正在等待通知,那么只有一个线程获得通知,而剩下的线程必须等 ...
- Java多线程wait()和notify()方法图解
多线程wait()和notify()方法详解 文章目录 多线程wait()和notify()方法详解 前言 一.线程间等待与唤醒机制 二.等待方法wait() 三.唤醒方法notify() 四.关于w ...
- 细说Java学习的捷径与方法
下面是Java学习的种种技巧,能让初学者少走很多弯路: 1.JDK就是J2SE,JDK1.1.8版本以后改成为J2SE 下载地址:http://Java.sun.com/J2SE/downloads. ...
- JAVA学习日志 关于调用方法、生成对象的例子。还是用数字卦程序修改
今天学习如何调用方法,生成,建立对象.将程序在原数字卦程序里做了很多修改.多了一个CalculateData对象,作为存储卦象信息,增加了名字,便于以后学会存储之后多人进行记录.输入部分从原来的nex ...
- Java学习篇十——关于方法的定义和使用
写在前面:本人是借助两本参考书自学的,其中部分例子和语句均是来自参考书.第一本:<Java 编程指南>,[美] Budi Kurniawan 著,闫斌 贺莲 译.第二本:<第一行代码 ...
- Java学习_day007:数组与方法
一.数组 数组的复制 int[]a={10,20,30,40,50}; int[]b=new int[6]; //b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4 ...
最新文章
- matlab用lism求零输入响应,信号与系统matlab课后作业_北京交通大学讲解.docx
- 从桌面向手机移植Silverlight应用
- 获取Servlet原生的API
- activemq网络桥接_ActiveMQ –经纪人网络解释–第2部分
- 内核抢占,让世界变得更美好 | Linux 内核
- 2021中国到店消费新趋势洞察报告
- git本地commit之后如何同步到远程
- Spring 的动态数据源实现
- UVA10338 Mischievous Children【组合数学】
- STM32 OSAL操作系统抽象层的移植
- 获取某网站在alexa上的排名
- 追本溯源,解密第一性原理(下)
- 华为否认Mate40升级鸿蒙传闻,华为鸿蒙系统什么时候上市?华为否认Mate40升级鸿蒙传闻...
- 系统集成项目应怎样管?本文经验值得借鉴
- 从零开始自学微信小程序(一)
- mosquitto 使用详解
- 解决:docker容器内可以访问web应用,端口映射到宿主机却无法访问,错误代码:curl: 56 Recv failure: 连接被对方重设
- liferay mysql_Liferay Portal使用MySQL数据库配置
- 跳槽谋发展:人生发展的一些思考和最近找工作的坎坷经历
- 计算机系统基础(第一章习题)