运行状态到死亡中的stop()方法过时了。
setDeamon()守护线程:
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(){
@Override
public void run() {
for(int i = 0; i<50; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + " --- " + i);
}
}
};
thread.setDaemon(true); //设置了守护线程
thread.start();
Thread.sleep(10000);
//默认是非守护线程
//非守护线程 主线程一直在等 Thread thread 到底执行完了没有
//走到这里 ,代表主线程结束,主线程结束,不管thread线程有没有结束,thread线程都必须结束,
// 因为thread线程是守护线程,守护了main
}
Thread-0 --- 0
Thread-0 --- 1
Thread-0 --- 2
Thread-0 --- 3
Thread-0 --- 4
Thread-0 --- 5
Thread-0 --- 6
Thread-0 --- 7
Thread-0 --- 8
Process finished with exit code 0
如果注释掉 thread.setDaemon(true); //设置了守护线程
那么主线程将等待thread线程走完为止
谁调用我,我就守护谁。
sleep()和wait()都可知导致阻塞
sleep静态方法强制当前正在执行的线程休眠,苏醒之前不会返回到可运行状态,当睡眠时间到期,则返回可运行状态。
sleep是休眠,等休眠时间一过,才有执行权的资格,注意:只是又有资格了,并不代表马上就会被执行,什么时候又执行起来,取决于操作系统调度。
调用某个对象的notify方法,能够唤醒一个正在等待这个对象的monitor。
含义的不同:sleep无条件可以休眠,wait是某些原因与条件需要等待一下(资源不满足)
停止线程补充
如果run()函数中有sleep(),那么sleep会把中断信号清除,sleep抛出异常的时候会把信号清除,所以停不下来。
在catch内部再发一次信号就可以了
sleep()会马上抛出异常,内部抛出异常,是通过异常的机制启动起来的,这个时候就会清除标记。发出异常,清除中断标记。
/**
* 类说明: 抛出InterruptedException异常的时候
*/
public class HasInterruptException {
private static SimpleDateFormat format
= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss_SSS");
private static class UseThread extends Thread{
public UseThread(String name){super(name);}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
while(!isInterrupted()) {
// TODO 第一版
System.out.println("线程内循环运行....");
// TODO 第二版
try {
System.out.println("UseThread:"+format.format(new Date()));
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println(threadName+" catch interrupt flag is "
+isInterrupted()+" at "
+(format.format(new Date())));
// TODO interrupt 需要在此内部 调用才能中断了,才能把被清楚的标记修改成true
interrupt();
e.printStackTrace();
}
System.out.println(threadName);
}
System.out.println(threadName+" interrupt flag is " +isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
UseThread useThread = new UseThread("HsInterruptEx");
useThread.start();
System.out.println("Main:"+format.format(new Date()));
Thread.sleep(800);
System.out.println("Main begin interrupt thread:" +format.format(new Date()) );
useThread.interrupt();
}
}
如何让出当前线程的执行权
yield方法,只在JDK某些内部实现才能看到,是让出执行权,基本用不到。让出之后变成可运行状态。
join的用途:顺序执行
join 来控制 让t1获取执行的权力,能够做到顺序执行。
/**
* 做到顺序执行
*/
class ThreadJoinTest extends Thread{
public ThreadJoinTest(String name){
super(name);
}
@Override
public void run() {
for(int i=0; i<100;i++){
System.out.println(this.getName() + ":" + i);
}
}
}
public class JoinTest{
public static void main(String[] args) throws InterruptedException {
ThreadJoinTest t1 = new ThreadJoinTest("AAA");
ThreadJoinTest t2 = new ThreadJoinTest("BBB");
t1.start();
/**join的意思是使得放弃当前线程的执行,并返回对应的线程,例如下面代码的意思就是
* 程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕
* 所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会
*/
t1.join();
t2.start();
}
}
......
AAA:98
AAA:99
BBB:0
BBB:1
BBB:2
......