1、线程死亡之后不能再次启动
测试线程是否已经死亡,可以调用isAlive()方法.当线程处于就绪、运行、阻塞三种状态时,返回true;当线程处于死亡、新建状态时返回false。
实例代码如下:
package com.thread;
public class StartDead extends Thread{
private int i;
@Override
public void run() {
for(;i<100;i++){
System.out.println(getName()+" "+i);
}
}
public static void main(String[] args) {
//创建线程对象
StartDead sd=new StartDead();
for(int i=0;i<300;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
//启动线程】
sd.start();
//判断启动后线程的isAlive()值,返回true
System.out.println(sd.isAlive());
}
//只有当线程处于新建、死亡两种状态时,isAlive()返回false
if(i>20&&!sd.isAlive()){
//试图再次启动该线程
try {
sd.start();
} catch (Exception e) {
System.out.println(sd.getName()+"线程已经死亡,无法再次启动!");
} }
}
}
}
运行上面代码我们可以发现,对已经死亡的线程,调用start()方法会抛出异常!
注意:不要对已经死亡的线程调用start()方法,程序只能对新建状态的线程调用start()方法,对新建线程两次调用start()方法也是错误的!
2.控制线程的运行
2.1 join()方法
join()方法有三种重载方式。
join(): 等待被join的线程执行完成.
join(long millis) :等待被join的时间最长为 .. millis。如果在..millis内,被join()的线程还没有完成,讲不再等待.
join(long millis,int nanos):等待被join的线程最长为..millis毫秒加上nanos微秒.
好吧,来个具体的例子看看下:
package com.thread;
public class JoinThread{
public static void main(String[] args) {
//启动子线程
Thread t1=new Thread(new MyJoinThread(),"新线程");
t1.start();
//运行主线程
for(int i=0;i<100;i++){
if(i==20){
Thread t2=new Thread(new MyJoinThread(),"被Join的线程");
t2.start();
try {
//mian 线程调用了t2线程的join()方法,main线程必须等待t2完成之后才能执行.
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
class MyJoinThread implements Runnable {
//重写run()方法,定义线程执行体
public void run() {
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
输出的结果如下,每次运行都不一样:
新线程 14
main 16
main 17
main 18
main 19
新线程 15
新线程 16
新线程 17
新线程 18
新线程 19
新线程 20
新线程 21
新线程 22
新线程 23
新线程 24
新线程 25
新线程 26
被Join的线程 0
新线程 27
被Join的线程 1
被Join的线程 2
由上述结果可以看出,当主线程的i=20的时候,主线程阻塞,直到被join的线程执行完才可以!在i=20之前,“新线程”和"main"线程交替执行,i=20之后,“新线程”和“join线程交替执行”.
2.2.后台线程
如果将某个线程设置为后台线程,必须在该线程启动之前设置,也就是说start()方法必须在setDaemon(true)方法之后,否则会抛出异常!
2.3 线程睡眠
static void sleep(long millis) ,让当前正在执行的线程暂停millis毫秒,并进入阻塞状态。调用sleep()不会释放对象锁!
package com.thread;
public class ThreadSleep {
public static void main(String[] args) {
Thread t=new Thread(new MySleep());
t.start();
}
}
class MySleep implements Runnable{
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
还有其它的一些小问题,有时间再补充吧!