join方法源码如下:
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);
//不明这里,如果是0的话,调用此方法的线程会一直等待下去,以 t.join()这种
//形式调用,调用此方法的线程是如何唤醒的呢
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
测试代码:class T extends Thread{
public void run(){
try{
Thread.currentThread().sleep(2000);
System.out.println("run!!!");
}catch(Exception e){}
}public static void main(String[] s)throws Exception{
T t=new T();
System.out.println("begin!");
t.start();
t.join();
System.out.println("end!");
}
}
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);
//不明这里,如果是0的话,调用此方法的线程会一直等待下去,以 t.join()这种
//形式调用,调用此方法的线程是如何唤醒的呢
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
测试代码:class T extends Thread{
public void run(){
try{
Thread.currentThread().sleep(2000);
System.out.println("run!!!");
}catch(Exception e){}
}public static void main(String[] s)throws Exception{
T t=new T();
System.out.println("begin!");
t.start();
t.join();
System.out.println("end!");
}
}
解决方案 »
- socket编程如何与外网同信
- 新手请教一下JAVA 服务器端编程如何实现 即时消息提醒?
- 帮下忙呗,就是个万年历
- 本人是写PHP的,有段JAVA看不懂,能帮忙翻译一下吗?
- Exception in thread "AWT-EventQueue-0" java.util.NoSuchElementException
- 关于java中的按值传递和按址传递
- 数据库中如何有效的读取数据?????
- 如何在TextArea中用自身手段强制换行?
- 哪位知道哪里有用JAVA编的搜索引擎源代码可以下载????
- 我现在用JBUILDER3在开发上落不落伍,也就是说,对于新型的应用,jbuilder3支持到什么程度?
- Java for循环的问题
- 紧急求助:怎样实现socket通信接收数据的超时处理
n(0);
}
我以前一直以为这是个自旋等待,因为我以为wait(0)会马上醒来
throws InterruptedException
如果 timeout 为零,则不考虑实际时间,该线程将一直等待,直到获得通知。 public final void join(long millis)
throws InterruptedException
等待该线程终止的时间最长为 millis 毫秒。超时为 0 意味着要一直等下去。设置为0就是要保证这个线程一定要执行完啊,0的时候还唤醒什么?要唤醒的话就设置为大于0
*
* @author bzwm
*
*/
class CustomThread1 extends Thread {
public CustomThread1() {
super("[CustomThread1] Thread");
}; public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " loop at " + i);
Thread.sleep(1000);
}
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}public class JoinTestDemo { private static int i = 0; private static boolean isAlive(Thread a) {
System.out.println("judge...." + i++);
return a.isAlive(); } public static void main(String args[]) throws Exception {
CustomThread1 a = new CustomThread1();
a.start();
Thread.sleep(100);
synchronized (a) {
System.out.println("CustomThread1 is alive or not??????");
while (isAlive(a)) {
System.out.println("CustomThread1 is alive.");
a.wait(0);
}
}
System.out.println("Done!");
}
}打印结果:
[CustomThread1] Thread start.
[CustomThread1] Thread loop at 0
CustomThread1 is alive or not??????
judge....0
CustomThread1 is alive.
[CustomThread1] Thread loop at 1
[CustomThread1] Thread loop at 2
[CustomThread1] Thread loop at 3
[CustomThread1] Thread loop at 4
[CustomThread1] Thread end.
judge....1
Done!在执行了a.wait(0);后,主线程就被阻塞了。当a线程返回后,程序继续运行,所以进行了第二次判断,
由于此时调用isAlive方法返回false,所以就不再阻塞了。在这里,确实没有看到调用 a.notify()的方法。再来看看jdk中对于wait方法的解释: * <li>The specified amount of real time has elapsed, more or less. If
* <tt>timeout</tt> is zero, however, then real time is not taken into
* consideration and the thread simply waits until notified. 从这里分析,
想弄清楚这个问题,得看看关于JVM的东西了。
while(condition){
wait();
}
other stmt;
这样的程序以,其唤醒一定是条件不满足时notify,否则就是设计错误。
换句话说,线程在wait什么?当然是wait noify动作。不过这只是表面上的,线程真正wait的是!condition,
也就是能执行other stmt;的条件。所以一但达到这样的条件,就一定会notify,通知在这个对象上wait的线程。
也就是改变状态的线程在条件不满足wait的时候一定会通知等待中的线程。为什么不是if(condition){
wait();
}而是
while(condition){
wait();
}这不是自旋,而是为了多线程安全性。
比如两个线程A,B执行到wait:if(listA.size() <= 0){
wait();
}
listA.removeFirst();
当线程C向listA中add一个元素并用notifyAll通知了wait的线程后,
假如线程A抢到锁并运行listA.removeFirst();然后切换到B,因为B已经从wait
中出来,所以肯定执行listA.removeFirst();而实际上这时listA.size() <= 0了。
所以如果用while的话,无论A还是B即使刚从wait中出来也会再一次检查条件。不会在
listA.size() <= 0时执行wait下面的的语句。