一、Thread的构造方法
常用的就前面的几个:
1.Thread(Runnable target)。参数为实现了Runnable接口的类。
2.Thread(String name)。参数为线程的名字。
3.Thread(Runnable target,String name)。
二、常用方法
start:启动线程。
yield:注意这是一个静态的方法。使当前运行线程释放处理器资源。
sleep:这也是一个静态方法,即使当前运行线程休眠millis毫秒。后一个参数nanos基本不起什么作用,源码只是对其做了四舍五入的判断,感兴趣的同学自行查阅。
join:Thread提供了让一个线程等待另一个线程完成的方法——join()方法。当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()加入的join()线程执行完为止。其中,join():等待被join()的线程执行完成后,调用线程再执行;join(long millis):调用线程等待被join的线程的时间最长为millis毫秒。如果在millis毫秒内被join的线程还没有执行结束,则不再等待。
下面用一段代码解释一下join方法:
public static void main(String[] args) throws InterruptedException {
//启动子线程
new JoinThread("新线程").start();
for(int i=0;i<100;i++){
if(i==20){
JoinThread jt=new JoinThread("被Join的线程");
jt.start();
//main线程调用了jt线程的join()方法,main线程
//必须等jt执行结束才会向下执行
jt.join();
}
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
上述代码中,在main方法中调用了jt线程,实际上main线程即为调用线程,jt即为被join()的线程。若执行jt.join(),则jt线程执行完main线程才会执行;若执行jt,join(2000),则若jt线程执行2000毫秒后仍未执行完,main线程也启动,和jt并行执行。
currentThread:返回当前正在运行的线程。
三、方法代码演示
下面通过一段有意思的代码演示各种方法。
//军队线程
//模拟作战双方的行为
public class ArmyRunnable implements Runnable {
//volatile保证了线程可以正确的读取其他线程写入的值
//可见性 ref JMM, happens-before原则
volatile boolean keepRunning = true;
@Override
public void run() {
while(keepRunning){
//发动5连击
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+"进攻对方["+i+"]");
//让出了处理器时间,下次该谁进攻还不一定呢!
Thread.yield();
}
}
System.out.println(Thread.currentThread().getName()+"结束了战斗!");
}
}
//关键历史人物线程
public class KeyPersonThread extends Thread {
public void run(){
System.out.println(Thread.currentThread().getName()+"开始了战斗!");
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"左突右杀,攻击隋军...");
}
System.out.println(Thread.currentThread().getName()+"结束了战斗!");
}
}
/**
* 隋唐演义大戏舞台
*/
public class Stage extends Thread {
public void run(){
System.out.println("欢迎观看隋唐演义");
//让观众们安静片刻,等待大戏上演
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("大幕徐徐拉开");
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("话说隋朝末年,隋军与农民起义军杀得昏天黑地...");
ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable();
ArmyRunnable armyTaskOfRevolt = new ArmyRunnable();
//使用Runnable接口创建线程
Thread armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"隋军");
Thread armyOfRevolt = new Thread(armyTaskOfRevolt,"农民起义军");
//启动线程,让军队开始作战
armyOfSuiDynasty.start();
armyOfRevolt.start();
//舞台线程休眠,大家专心观看军队厮杀
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正当双方激战正酣,半路杀出了个程咬金");
Thread mrCheng = new KeyPersonThread();
mrCheng.setName("程咬金");
System.out.println("程咬金的理想就是结束战争,使百姓安居乐业!");
//停止军队作战
//停止线程的方法
armyTaskOfSuiDynasty.keepRunning = false;
armyTaskOfRevolt.keepRunning = false;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/*
* 历史大戏留给关键人物
*/
mrCheng.start();
//万众瞩目,所有线程等待程先生完成历史使命
try {
/*
* 这里的join参数如果设为1毫秒,则若KeyPersonThread中人物攻击次数很多,也就是1毫秒之内mrCheng线程无法执行完,
则main线程会启动,与mrCheng线程并行执行。此时会出现执行完System.out.println("谢谢观看隋唐演义,再见!");
后程咬金仍然在攻击的情况
*/
mrCheng.join(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("战争结束,人民安居乐业,程先生实现了积极的人生梦想,为人民作出了贡献!");
System.out.println("谢谢观看隋唐演义,再见!");
}
public static void main(String[] args) {
new Stage().start();
}
}