zoukankan      html  css  js  c++  java
  • 多线程的一些小问题集锦

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

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

  • 相关阅读:
    打印图形II
    打印图形
    17倍
    进制转换
    小球
    最强素数
    最强阵容
    英雄卡
    数论模板
    畅通工程 (最小生成树)(最短路径和)
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300448.html
Copyright © 2011-2022 走看看