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的更多相关文章

  1. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

  2. Java多线程技术:实现多用户服务端Socket通信

    目录 前言回顾 一.多用户服务器 二.使用线程池实现服务端多线程 1.单线程版本 2.多线程版本 三.多用户与服务端通信演示 四.多用户服务器完整代码 最后 前言回顾 在上一篇<Java多线程实 ...

  3. 赶紧收藏!王者级别的Java多线程技术笔记,我java小菜鸡愿奉你为地表最强!

    Java多线程技术概述 介绍多线程之前要介绍线程,介绍线程则离不开进程. 首先 , 进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元: 线程:就 ...

  4. Java多线程:wait(),notify(),notifyAll()

    1. wait(),notify(),notifyAll() 2. wait() 2.1. wait() 2.2. wait(long timeout) 2.3. wait(long timeout, ...

  5. java多线程中wait/notify/sleep/join/yield方法以及多线程的六种状态

    刚开始学线程的时候也是被这几个方法搞的云里雾里的,尤其是一开始看的毕老师的视频,老师一直在强调执行权和执行资格,看的有点懵逼,当然不是说毕老师讲的不好,就是自己有点没听明白,后来复习看了一些其他的博客 ...

  6. java多线程技术核心

    1.进程的三大特征: 独立性:拥有自己的独立的地址空间,一个进程不可以直接去访问其他进程的地址空间. 动态性:是一个系统中活动的指令的集合. 并发性:单个进程可以在多个处理器上并发进行,互不影响. 2 ...

  7. (转载) Java多线程技术

    多线程编程一直是学员们比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上java内置 ...

  8. Java多线程技术学习笔记(一)

    目录: 概述 多线程的好处与弊端 JVM中的多线程解析 多线程的创建方式之一:继承Thread类 线程的状态 多线程创建的方式之二:实现Runnable接口 使用方式二创建多线程的好处 多线程示例 线 ...

  9. Java多线程的wait(),notify(),notifyAll()

    在多线程的情况下.因为多个线程与存储空间共享相同的过程,同时带来的便利.它也带来了访问冲突这个严重的问题. Java语言提供了一种特殊的机制来解决这类冲突,避免同一数据对象由多个线程在同一时间访问. ...

随机推荐

  1. ICMP,ARP协议

    ICMP ICMP是(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议族的一个子协议,用于在IP主机.路由器之间传递控制消息.控制 ...

  2. ubuntu下查看如何配置pycharm

    ubuntu中PyCharm的安装与卸载 https://blog.csdn.net/weixin_31484477/article/details/81133590 pycharm ModuleNo ...

  3. Springboot启动工程后,浏览器出现输入用户名和密码

    在使用spring boot的时候发现启动项目时,浏览器需要输入用户名和密码. baidu后发现是因为pom中引用了Spring Security,但是项目中没有使用,在pom中注释掉即可.

  4. BZOJ 2096: [Poi2010]Pilots 单调队列

    Code: #include<bits/stdc++.h> #define maxn 4000000 using namespace std; void setIO(string s) { ...

  5. Mac 执行 gulp 报错 -bash: gulp: command not found

    在mac系统下安装gulp,之后执行gulp 报如下错误: -bash: gulp: command not found 回溯安装过程发现问题如下 1.执行 npm root: Application ...

  6. 洛谷——P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm

    P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题意翻译 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N< ...

  7. MySQL之索引以及正确使用索引

    一.MySQL中常见索引类型 普通索引:仅加速查询 主键索引:加速查询.列值唯一.表中只有一个(不可有null) 唯一索引:加速查询.列值唯一(可以有null) 组合索引:多列值组成一个索引,专门用于 ...

  8. C C++ POSIX 的一些 IO 操作

    一些 C C++ POSIX 的 IO 操作总结 文件-内存之间 内存-内存之间 POSIX 有无缓冲的 IO 操作 对文件的操作,读文件至内存,从内存写至文件 // 读文件至内存buf中 void ...

  9. 用Twebbrowser做可控编辑器与MSHTML(插入表格)

    在插入表格问题上出现与结果想象不一样的问题.看代码 <table border="1" cellpadding="0" width="100%& ...

  10. 【codeforces 509C】Sums of Digits

    [题目链接]:http://codeforces.com/contest/509/problem/C [题意] 给你一个数组b[i] 要求一个严格升序的数组a[i]; 使得a[i]是b[i]各个位上的 ...