题外话:

interrupt()方法  并不能中断一个正常运行的线程!!!

class myThread extends Thread{
@Override
public void run(){
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}
public class waitTest { public static void main(String[] args) throws Exception{
Thread t =new myThread();
t.start();
t.interrupt();
System.out.println("mark");
} }

输出:

mark

......

i=999

public class waitTest {

    public static void main(String[] args) throws Exception{

        Thread.currentThread().interrupt();
System.out.println("是否停止1?" + Thread.interrupted());
System.out.println("是否停止2?" + Thread.interrupted());
System.out.println("end!");
} }

此时的输出为

是否停止1?true
是否停止2?false
end!

interrupt虽然不能中断一个正常执行的线程,但是会将目标线程的中断状态置为true   而interrupted用于测试当前线程的中断状态,执行后将状态表示置为false

而且interrupt只能中断一个正处于‘‘异常’’状态的线程

class myThread extends Thread{
@Override
public void run(){
for (int i = 0; i < 1000; i++) { System.out.println(i);
if(i==800){
try{
Thread.sleep(1000);
}catch (Exception e){
System.out.println(i+"$$");
e.printStackTrace();
System.out.println(i+"^^"); }
}
}
}
}
public class waitTest { public static void main(String[] args) throws Exception{ Thread t =new myThread();
t.start();
t.interrupt();
System.out.println("end");
} }

输出为:

end    //说明interrupt已经发送

0

...

800
800$$   //说明确实是在i=800 处抛出异常  不过异常信息打印的稍有延迟???
800^^
801

912

java.lang.InterruptedException: sleep interrupted
913
914
at java.lang.Thread.sleep(Native Method)
915
at luyudepackage.myThread.run(waitTest.java:22)

...

999

说明interrupt方法可以提前发送 将目标线程中断状态置为true 当目标线程进入sleep状态时 抛出异常


join()方法

具体用法http://www.cnblogs.com/luyu1993/p/7017927.html

这里看下它的源码

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;
}
}
}

  

join()内部调用的是wait()  注意 在调用wait()之前,线程必须获得该对象的锁,因此只能在同步方法/同步代码块中调用wait()方法。可以看见join()方法是synchronized的 所以没问题

看下面这段代码

 class myThread extends Thread{
@Override
public void run(){
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}
public class waitTest { public static void main(String[] args) throws Exception{
Thread t =new myThread();
t.start();
Thread.currentThread().wait();
System.out.println("mark");
} }

此时程序会报错  不在同步方法/同步代码块 中调用wait()方法的错误!!!

多次start同一个线程

JAVA多线程---wait() & join()的更多相关文章

  1. Java多线程中join、yield、sleep方法详解

    在Java多线程编程中,Thread类是其中一个核心和关键的角色.因此,对该类中一些基础常用方法的理解和熟练使用是开发多线程代码的基础.本篇主要总结一下Thread中常用的一些静态方法的含义及代码中的 ...

  2. 转载:Java多线程中join方法的理解

    转载自:http://uule.iteye.com/blog/1101994 thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A ...

  3. Java多线程的join()

    假设在main线程里又起了一个thread1线程,在调用了thread1.start()之后: 如果在main线程里调用了thread1.join(),那么main线程将会block,直到thread ...

  4. Java多线程中join方法详解

    join()方法用于让当前执行线程等待join线程执行结束.其实现原理是不停的检查join线程是否存活,如果join线程存活则让当前线程永远等待. join()方法部分实现细节 while(isAli ...

  5. Java多线程中join方法的理解

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. t.join( ...

  6. Java多线程学习——join方法的使用

    join在线程里面意味着“插队”,哪个线程调用join代表哪个线程插队先执行——但是插谁的队是有讲究了,不是说你可以插到队头去做第一个吃螃蟹的人,而是插到在当前运行线程的前面,比如系统目前运行线程A, ...

  7. java 多线程 Thread.join子线程结束父线程再运行;join(long):等待超时毫秒数

    Join的使用 目的:当子线程运行结束后,父线程才能再继续运行 /** * @ClassName ThreadJoinExample * @projectName: object1 * @author ...

  8. Java多线程-join方法

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. 具体例子看链接 ...

  9. Java多线程系列--“基础篇”08之 join()

    概要 本章,会对Thread中join()方法进行介绍.涉及到的内容包括:1. join()介绍2. join()源码分析(基于JDK1.7.0_40)3. join()示例 转载请注明出处:http ...

随机推荐

  1. [Caffe]史上最全的caffe安装过程

    Linux下的GPU版Caffe安装方法 系统环境:Ubuntu 14.04LTS + NV TitanX 1.1 (可选)显卡驱动的安装(有风险) 如果需要重装,需要先卸载已有版本 sudo apt ...

  2. Go 到底有没有引用传参(对比 C++ )

    Go 到底有没有引用传参(对比 C++ ) C++ 中三种参数传递方式 值传递: 最常见的一种传参方式,函数的形参是实参的拷贝,函数中改变形参不会影响到函数外部的形参.一般是函数内部修改参数而又不希望 ...

  3. 关于RequestDispatcher的原理

    RequestDispatcher简介 RequestDispatcher 代表请求的派发者.它有2个动作:forward 和 include .客户端对于任何一个请求,可以根据业务逻辑需要,选择不同 ...

  4. web安全普及:通俗易懂,如何让网站变得更安全?以实例来讲述网站入侵原理及防护。

    本篇以我自己的网站[http://www.1996v.com]为例来通俗易懂的讲述如何防止网站被入侵,如何让网站更安全. 要想足够安全,首先得知道其中的道理. 本文例子通俗易懂,从"破解网站 ...

  5. 九天学会Java,第五天,函数定义函数调用

    变量和数据类型,赋值和输出 算术运算 选择结构 循环结构 函数定义,函数调用 变量作用域 栈,程序运行的基石 面向对象 异常处理 语言提供的公用包 什么是函数,为什么有函数,大家可能有这样的疑问. 举 ...

  6. StringBuffer .insert方法输出电话号码格式

    package ch11; import java.util.Scanner; /** * Created by liwenj on 2017/7/21. */public class T7 { pu ...

  7. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  8. CSS基础用法

    [CSS常用选择器] 标签选择器 写法: HTML标签名{}作用: 可以选中页面中,所有与选择器同名的HTML标签. 类选择器(class选择器)写法: .class名{}调用: 在需要调用选择器样式 ...

  9. 极化码的matlab仿真(2)——编码

    第二篇我们来介绍一下极化码的编码. 首先为了方便进行编码,我们需要进行数组的定义 signal = randi([0,1],1,ST); %信息位比特,随机二进制数 frozen = zeros(1, ...

  10. [js高手之路]深入浅出webpack教程系列3-配置文件webpack.config.js详解(下)

    本文继续接着上文,继续写下webpack.config.js的其他配置用法. 一.把两个文件打包成一个,entry怎么配置? 在上文中的webpack.dev.config.js中,用数组配置entr ...