多线程的一些小问题集锦

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值