Java多线程--wait和join
首先从公司一道笔试题开始
package test;
public class Test implements Runnable {
public int i = 0;
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i = 10;
}
public static void main(String[] args) {
try {
Test t = new Test();
Thread th = new Thread(t);
th.start();
th.join();
System.out.println(t.i);
} catch (Exception ex) {
}
}
}
问23行代码怎么写,才能让24行打印出10?
不少笔试者会选t.wait()或者th.wait()!
面试的时候问他为什么,他具体也说不清楚,感觉就是见过这个wait方法,但是wait方法的含义确一知半解。
wait 是什么意思呢?我举例子啊,比如我想让本线程放弃当前对象锁,说直白点就是让别的对象进入同步块
package test;
public class Test implements Runnable {
public Object i = new Object();
@Override
public void run() {
synchronized (i) {
System.out.println(Thread.currentThread().getName()+"enter ");
// i.notify();
try {
i.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"out ");
}
}
public static void main(String[] args) {
try {
Test t = new Test();
Thread th1 = new Thread(t);
Thread th2 = new Thread(t);
th1.start();
th2.start();
} catch (Exception ex) {
}
}
}
如上例,你会看到输出
Thread-0enter
Thread-1enter
不会看到
Thread-1out
Thread-0out
因为Thread-0 先获得了Object i 锁,然后运行到13行,释放了该锁,
这个时候Thread-1就获得了Object i 锁,进入了同步代码块,然后同样运行13行,也释放了该锁。
这个时候在有两个线程Thread-0和Thread-1等待获得Object i 锁,由于代码中没有调用i.notifyAll(),所以这个程序永远不会退出。
但是如果打开注释11行,那么你将会看到结果
Thread-0enter
Thread-1enter
Thread-0out
因为Thread-0 先获得了Object i 锁,然后运行到13行,释放了该锁,
这个时候Thread-1就获得了Object i 锁,进入了同步代码块,运行到11行,i.notify(),
那么这个意思就是说别的等待i锁的线程可以唤醒了,一旦我(Thread-1)释放锁(13行调用wait()),那么Thread-0就可以获得i锁继续执行了。
此程序中没有在Thread-1 释放i锁(wait())之后notify,所以永远不会看到Thread-1out
再回到这个题目,我们的意思是让主线程等待所有子线程执行完毕 ,再执行。更何况笔试题中没有锁对象。更别提wait()了。
所以,此处应该用th.join(); Thread.join()方法会阻塞主线程继续向下执行。
public class TestThread extends Thread
{
private CountDownLatch countDownLatch; public TestThread(CountDownLatch countDownLatch)
{
this.countDownLatch = countDownLatch;
} public void run()
{
System.out.println(this.getName() + "子线程开始");
try
{
// 子线程休眠五秒
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
} System.out.println(this.getName() + "子线程结束"); // 倒数器减1
countDownLatch.countDown();
}
}
public class Main
{
public static void main(String[] args)
{
long start = System.currentTimeMillis(); // 创建一个初始值为5的倒数计数器
CountDownLatch countDownLatch = new CountDownLatch(5);
for(int i = 0; i < 5; i++)
{
Thread thread = new TestThread(countDownLatch);
thread.start();
} try
{
// 阻塞当前线程,直到倒数计数器倒数到0
countDownLatch.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
} long end = System.currentTimeMillis();
System.out.println("子线程执行时长:" + (end - start));
}
}
Java多线程--wait和join的更多相关文章
- java多线程wait notify join
wait notify 几个注意点: wait 与 notify/notifyAll 方法必须在同步代码块中使用,即要先对调用对象加锁. 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进 ...
- java 多线程8(join)
join(): 加入.一个线程如果执行了join语句,那么就有新的线程加入,执行该语ij 句的线程必须要让步给新加入的线程先完成任务,然后才能继续执行. import java.util.Scann ...
- Java多线程中的join()方法
一.join()方法介绍 join() 定义在Thread.java中.join()方法把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的join( ...
- 浅谈Java多线程中的join方法
先上代码 新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String ...
- Java多线程中的join方法
新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String name ...
- java多线程中关于join方法的使用
Thread的非静态方法join()让一个线程B"加入"到另外一个线程A的尾部.在A执行完毕之前,B不能工作.例如: Thread t = new MyThread ...
- thread.join函数,java多线程中的join函数解析
join函数的作用,是让当前线程等待,直到调用join()的 线程结束或者等到一段时间,我们来看以下代码 package mian; public class simpleplela { static ...
- Java多线程10:join()方法
一.前言 通过一个简单的例子引入join()方法 public class Thread01 extends Thread{ @Override public void run() { for(int ...
- java多线程16:join()的使用
讲解join()方法之前请确保对于即wait()/notify()/notifyAll()机制已熟练掌握.可以参考前面的笔记 join()方法的作用是等待线程销毁.join()方法反应的是一个很现实的 ...
随机推荐
- ListView.DragEnter触发不了
经过千百度的搜索之后,终于找到了一点线索,原文是:https://msdn.microsoft.com/en-us/magazine/mt185571.aspx 有能力的可以参阅原文,想省事的可以等待 ...
- 各种边缘检测算子特点比较(canny)
canny 最好.但是容易把噪点误判为边界.sobel prewitt log 效果差不多.prewitt比sobel 去噪效果好.roberts马马虎虎.适合什么图片那得看图片的噪点情况,一般can ...
- Rest接口测试,巧用firebug插件
两年前开始做软件测试,刚接触的是关于rest接口的测试.作为一个刚进职场的测试小菜鸟,当时对接口的理解并不是很充分,具体是怎么实现的也不清楚.在进行接口测试时,只是设置接口入参,调用接口,查看接口是否 ...
- hdoj 4323
题意:给你n个数,m个查询,查询中包括一个数和一个最大编辑距离d,问n个数中和这个数的编辑距离不超过d的有多少个 编辑距离:http://baike.baidu.com/view/2020247.ht ...
- mysql之存储过程
一.存储过程 迄今为止,使用的大多数 SQL语句都是针对一个或多个表的单条语句.并非所有操作都这么简单,经常会有一个完整的操作需要多条语句才能完成.例如,考虑以下的情形. 1. ...
- Java中的HashSet和TreeSet
1:Set集合(理解) (1)Set集合的特点 无序,唯一 (2)HashSet集合(掌握) A:底层数据结构是哈希表(是一个元素为链表的数组) B:哈希表底层依赖两个方法:hashCode()和eq ...
- Ubuntu中安装eclipse ,双击eclipse出现invalid configuration location问题
ubuntu invalid configuration location 标签: myeclipse for ubuntu ubuntu myeclipse ubuntu安装myecli ...
- phonegap 框架详解
首先, 来看一下phonegap 初始化流程以及Native 与 JS 交互流程图. 说明:socket server模式下, phonegap.js 源码实现的采用1 毫秒执行一次XHR请求, 当 ...
- github使用心的
Git是一个分布式的版本控制系统,最初由LinusTorvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中.包括Rubinius和Mer ...
- Android 学习第2课,下载 eclipse 工具
可以到http://www.ddooo.com/softdown/61745.htm 下载下来是32位与64位都有的 而且是汉化的,经测试成功,还可以,不错!