多线程的一些小问题集锦

来源:互联网 发布:mac安全控件 编辑:程序博客网 时间:2024/05/21 19:22

1、线程死亡之后不能再次启动

测试线程是否已经死亡,可以调用isAlive()方法.当线程处于就绪、运行、阻塞三种状态时,返回true;当线程处于死亡、新建状态时返回false。

实例代码如下:

package com.thread;public class StartDead extends Thread{   private int i;   @Overridepublic 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()值,返回trueSystem.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);}}}


输出的结果如下,每次运行都不一样:

新线程  14main 16main 17main 18main 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();}}}}

 还有其它的一些小问题,有时间再补充吧!