线程的控制与同步

一、线程的生命周期

新建、就绪、运行、阻塞、死亡5种状态

使用new创建线程时处于新建状态(JVM为其分配内存,初始化变量),start时线程处于就绪

状态(JVM为其创建方法调用栈和程序计数器)。

启动线程的方法是调用start()方法,而不是run()方法,若调用run()方法,则会把run()方法当其一般方法执行。

并且在调用了run方法后,线程不在处于新建状态,

再去调用start()方法会出现IllegaThreadStateException异常。

线程状态转换图

二.控制线程

(1)、join线程

作用:让一个线程等待另一个线程。当一个线程调用其他线程的join( )方法时,调用线程阻塞,直

到被join方法加入的join线程执行完毕为止。

[java]  view plain  copy
  1. package Thread;  
  2. /* 
  3.  * 该类具有三个线程,main方法执行启动了子线程,它与main线程并行执行,当 
  4.  * mian线程的i=0时就会启动join线程,此时main线程被阻塞,直到join执行 
  5.  * 完毕,才会重新启动 
  6.  */  
  7. public class ThreadJoin extends Thread{  
  8.   
  9.     //提供一个有参的构造器用于设置线程名  
  10.     public ThreadJoin(String name) {  
  11.         super(name);  
  12.     }   
  13.       
  14.     //重写run()方法  
  15.     public void run() {  
  16.         for(int i =0;i<100;i++) {  
  17.             System.out.println(getName()+i);  
  18.         }  
  19.     }  
  20.     public static void main(String[] args) throws InterruptedException {  
  21.         //启动子线程  
  22.         new ThreadJoin("子线程:").start();  
  23.         for(int i =0;i<100;i++) {  
  24.             if(i==20) {  
  25.                 //执行join的线程  
  26.                 ThreadJoin tj = new ThreadJoin("被join的线程:");  
  27.                 tj.start();  
  28.                 tj.join();  
  29.             }  
  30.             System.out.println(Thread.currentThread().getName()+i);  
  31.         }  
  32.     }  
  33. }  

说明:join()方法常用的两种类型:

join( );等待被join的线程执行完毕

join(long millis):等待被join的线程最长时间为millis,超过这个时间没执行完不会在等待

(2)、后台线程(守护线程、精灵线程)

运行在后台,是为其他线程服务的线程,JVM的GC线程就是一种典型的后台线程;

特征:所有前台线程都死亡,后台线程自动死亡

使用方法:调用setDaemon(true)方法可以将一个线程设置为后台线程

[java]  view plain  copy
  1. package Thread;  
  2.   
  3. public class DaemonThread extends Thread{  
  4.   
  5.     //重写run()方法  
  6.     public void run() {  
  7.         for(int i =0;i<100;i++) {  
  8.             System.out.println(getName()+" "+i);  
  9.         }  
  10.     }  
  11.     public static void main(String[] args) {  
  12.         DaemonThread dt = new DaemonThread();  
  13.         //设置为守护线程  
  14.         dt.setDaemon(true);  
  15.         dt.start();  
  16.         for(int i =0;i<10;i++) {  
  17.             System.out.println(Thread.currentThread().getName()+" "+i);  
  18.         }  
  19.     }  
  20. }  
运行此程序会发现,在main线程(前台线程)执行完后,设置的后台线程是无法执行完毕的。

(3)、睡眠线程:sleep

让线程暂停并进入阻塞状态,调用sleep()方法实现;

sleep()方法的两种重载形式,

static void sleep(long millis)让线程暂停millis毫秒;

static void sleep(long millis,int nanos)让线程暂停millis毫秒j加毫微秒;

[java]  view plain  copy
  1. package Thread;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class SleepThread extends Thread {  
  6.   
  7.     public static void main(String[] args) throws InterruptedException {  
  8.         for(int i=0;i<10;i++) {  
  9.             System.out.println("当前时间:"+new Date());  
  10.             Thread.sleep(2000);  
  11.         }  
  12.     }  
  13. }  

(4)、线程让步:yield

猜你喜欢

转载自blog.csdn.net/zhang1223665986/article/details/80667100
今日推荐