Java多线程技术-wait/notify/join
wait/notify的作用
wait()方法的作用是使当前执行代码的线程进行等待,wait()是Object类的方法,用来将当前线程置入预执行队列中,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止。wait()调用前,必须获得该对象的对象级锁,即只能在同步方法或者同步代码块中调用wait()方法,否则会抛出IllegalMonitorStateException。当wait()执行后,当前线程释放锁
notify()方法的作用是用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则随机挑选出一个wait状态的线程,对其发出通知,并使它等待获取该对象的对象锁。notify()调用前,必须获得该对象的对象级锁,即只能在同步方法或者同步代码块中调用notify()方法,否则会抛出IllegalMonitorStateException。当notify()方法执行后,不会马上释放该对象的锁,呈wait状态的线程也并不能马上获得该对象锁,要等到执行notify()的线程将程序执行完,也就是退出synchronized代码块后,当前线程才会释放锁。
notifyAll()方法和notify()作用基本是一样的,一个是唤醒全部的wait线程,一个是唤醒其中一个wait线程。
经典案例生产者和消费者
public class MyStack {
private List<String> list = new ArrayList<>();
public synchronized void push() {
try {
while (list.size() == 1) {
System.out.println("push:"+Thread.currentThread().getName()+"呈wait状态");
this.wait();
}
list.add("anyString=" + Math.random());
this.notifyAll();
System.out.println("push=" + list.size());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized String pop(){
String returnValue = "";
try {
while(list.size() == 0){
System.out.println("pop:"+Thread.currentThread().getName()+"呈wait状态");
this.wait();
}
returnValue = list.get(0);
list.remove(0);
this.notifyAll();
System.out.println("pop="+list.size());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return returnValue;
}
}
public class Product {
private MyStack myStack;
public Product(MyStack myStack) {
this.myStack = myStack;
}
public void pushService(){
myStack.push();
}
}
public class Customer {
private MyStack myStack;
public Customer(MyStack myStack) {
this.myStack = myStack;
}
public void popService(){
myStack.pop();
}
}
public class ThreadCustomer extends Thread {
private Customer customer;
public ThreadCustomer(Customer customer) {
this.customer = customer;
}
@Override
public void run() {
while(true){
customer.popService();
}
}
}
public class ThreadProduct extends Thread {
private Product product;
public ThreadProduct(Product product) {
this.product = product;
}
@Override
public void run() {
while(true){
product.pushService();
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
MyStack myStack = new MyStack();
Product p = new Product(myStack);
Customer c = new Customer(myStack);
ThreadProduct pThread = new ThreadProduct(p);
ThreadCustomer cThread = new ThreadCustomer(c);
pThread.start();
cThread.start();
}
}
join的作用
join()是Thread类的一个方法,它的作用是使所属的线程x对象正常的执行run方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行线程z后面的代码。
public class MyThread extends Thread{
@Override
public void run() {
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
myThread.join();
System.out.println("在myThread执行完后输出:" + System.currentTimeMillis());
}
}
测试结果:
1516170164683
在myThread执行完后输出:1516170167686
join和synchronized的区别
从上面的例子可以看出,join方法具有线程排队运行的作用,有些类是同步的运行效果。join和synchronized的区别是:join在内部使用wait()方法进行等待,而synchronized是使用“对象监视器”原理做为同步
join(long)和sleep(long)的区别
由于join的内部是使用wait来实现的,所以它具有释放锁的特点,而sleep没有这一特点。
源码如下:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0; if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
} if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
Java多线程技术-wait/notify/join的更多相关文章
- Java多线程技术学习笔记(二)
目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...
- Java多线程技术:实现多用户服务端Socket通信
目录 前言回顾 一.多用户服务器 二.使用线程池实现服务端多线程 1.单线程版本 2.多线程版本 三.多用户与服务端通信演示 四.多用户服务器完整代码 最后 前言回顾 在上一篇<Java多线程实 ...
- 赶紧收藏!王者级别的Java多线程技术笔记,我java小菜鸡愿奉你为地表最强!
Java多线程技术概述 介绍多线程之前要介绍线程,介绍线程则离不开进程. 首先 , 进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元: 线程:就 ...
- Java多线程:wait(),notify(),notifyAll()
1. wait(),notify(),notifyAll() 2. wait() 2.1. wait() 2.2. wait(long timeout) 2.3. wait(long timeout, ...
- java多线程中wait/notify/sleep/join/yield方法以及多线程的六种状态
刚开始学线程的时候也是被这几个方法搞的云里雾里的,尤其是一开始看的毕老师的视频,老师一直在强调执行权和执行资格,看的有点懵逼,当然不是说毕老师讲的不好,就是自己有点没听明白,后来复习看了一些其他的博客 ...
- java多线程技术核心
1.进程的三大特征: 独立性:拥有自己的独立的地址空间,一个进程不可以直接去访问其他进程的地址空间. 动态性:是一个系统中活动的指令的集合. 并发性:单个进程可以在多个处理器上并发进行,互不影响. 2 ...
- (转载) Java多线程技术
多线程编程一直是学员们比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上java内置 ...
- Java多线程技术学习笔记(一)
目录: 概述 多线程的好处与弊端 JVM中的多线程解析 多线程的创建方式之一:继承Thread类 线程的状态 多线程创建的方式之二:实现Runnable接口 使用方式二创建多线程的好处 多线程示例 线 ...
- Java多线程的wait(),notify(),notifyAll()
在多线程的情况下.因为多个线程与存储空间共享相同的过程,同时带来的便利.它也带来了访问冲突这个严重的问题. Java语言提供了一种特殊的机制来解决这类冲突,避免同一数据对象由多个线程在同一时间访问. ...
随机推荐
- C# 返回值为 list<T>
public List<T> test<T>(List<T> EntityList) where T : class { return EntityList; }
- 吐得了,vue的多选组合框回显必须是字符串集合
下面这个typeIdList,如果给他赋值,就能回显到页面,但是必须是字符串的集合,如果是数值类型的id,不好意思,请转成字符串
- 零基础到精通Linux,从这篇文章开始
2018年想做Linux运维的人应该如何学习才能快速精通Linux? Linux入门这么简单,为什么很多人学不会? 想要成为一个合格的运维工程师,到底怎么才能从零开始精通Linux? 作为一个运维小白 ...
- [工具]iostat
本文主要分析了Linux的iostat命令的源码 iostat源码共563行,应该算是Linux系统命令代码比较少的了.源代码中主要涉及到如下几个Linux的内核文件: 1./proc/disksta ...
- emacs 定制进缩风格
纵览 emacs 文档中描述,进缩风格实现只需要两步:第一步,根据内容与上下文找到对应的进缩风格的类别:第二步,依据进缩风格决定的表达式锚点的进缩偏移.下面我们对 cc-mode 风格定制加以说明. ...
- 修改bash命令提示符
说明:PS1是主要的提示符设置,在ubuntu一般为: ${debian_chroot:+($debian_chroot)}\u@\h:\w\$ 具体的提示符,按分类含义如下: 主要信息: \u 当前 ...
- BZOJ 1572 USACO 2009 Open 工作安排
先把工作按照Deadline从小到大排序 然后按顺序取,deadline大于现在总用时就取,等于现在总用时就从前面已取的工作中找一个P最小的同它比较,取P较大的一个 用优先队列维护已取工作中P的最小值 ...
- (问题待解决)sql查询不显示前置‘0’的问题
SELECT * , ,),() ) ' end)) from CourseBooksNotes ),)),)+'秒'; ),)),)),)+'秒'
- 【LeetCode Weekly Contest 26 Q2】Longest Uncommon Subsequence II
[题目链接]:https://leetcode.com/contest/leetcode-weekly-contest-26/problems/longest-uncommon-subsequence ...
- elasticsearch 权威指南Mapping(映射)
什么是映射 类似于数据库中的表结构定义,主要作用如下: 定义Index下字段名(Field Name) 定义字段的类型,比如数值型,字符串型.布尔型等 定义倒排索引的相关配置,比如是否索引.记录pos ...