星期日, 十二月 06, 2015 17:49:26
?
四、线程的状态
4.1 概念
? ? ? 任何一个线程一般都具有5种状态:
? ? ? ? ? ? ? 创建、就绪、运行、阻塞、终止
在给定时间点上,一个线程只能处于一种状态
? ? ? ?1.new : 至今尚未启动的线程处于的状态
? ? ? ?2.runnable: 正在javav虚拟机中执行的线程
? ? ? ?3.blocked:受阻塞并等待某个监视器锁的线程
? ? ? ?4.waiting: 无限期的等待另一个线程来执行某一特定操作的线程
? ? ? ?5.timed_waiting:等待另一个线程来执行取决于指定等待时间的操作的线程
? ? ? ?6.te rminated:已退出的线程
?
4.2取得和设置线程的名称
? ? ? ? ? ? ?在Thread类中,可以通过getName()方法取得线程的名称,通过setName()方法设置线程的名称。
? ? ? ? ? ? ? 线程的名称一般在启动线程前设置,但也允许为已运行的线程设置名称。
? ? ? 允许两个Thread对象有相同的名字,但为了清晰,应该尽量避免这种情况的发生。
? ? ? ? ? ? ?另外,如果程序并没有为线程指定名称,系统会自动为线程分配名称。
?
4.2.1线程名称的分配
355--366 ?371 379 ?381
?
4.2.1代码案例:
package day34; public class ThreadGetName extends Thread{ public static void main(String[] args) { ThreadGetName tgn = new ThreadGetName(); tgn.start(); for(int i =0;i<3;i++) { tgn.printMsg(); } } public void run() { for(int i=0;i<3;i++){ printMsg(); } } @SuppressWarnings("static-access") private void printMsg() { // TODO Auto-generated method stub //获得运行此代码的线程的引用 Thread tn = new Thread(); String name = tn.currentThread().getName(); System.out.println("name --- "+name); } } 运行结果: name --- main name --- main name --- main name --- Thread-0 name --- Thread-0 name --- Thread-0
?注意:
? ? ?1.main()方法也是一个线程,实际上在命令行运行java命令时,就启动了一个JVM的进程,
? ? ? ?默认情况下此进程会产生两个线程:
? ? ? ? ? ? 1.一个是main()方法线程 ?2.一个就是垃圾回收(gc)线程
?
4.2.2在线程中设置线程的名称
?
代码案例:
package day34; public class ThreadSetName extends Thread { public static void main(String[] args){ @SuppressWarnings("unused") ThreadSetName tsn = new ThreadSetName(); //设置线程的名称 tsn.setName("test thread"); tsn.start(); for(int i=0;i<3;i++) { tsn.printMsg(); } } public void run() { for(int i =0;i<3;i++) { printMsg(); } } @SuppressWarnings("static-access") private void printMsg() { // TODO Auto-generated method stub Thread trd = new Thread(); String name = trd.currentThread().getName(); System.out.println("name---"+name); } } 运行结果: name---main name---test thread name---main name---test thread name---test thread name---main
?4.3判断线程是否启动
? ? ?在程序中也可以通过isAlive()方法来测试线程是否已经启动而且仍然在启动。
package day34; public class ThreadStartDemo extends Thread { public static void main(String[] args){ @SuppressWarnings("unused") ThreadStartDemo tsn = new ThreadStartDemo(); //设置线程的名称 tsn.setName("test thread"); System.out.println("在调用start()之前,tsn.isAlive() :"+tsn.isAlive()); tsn.start(); System.out.println("在调用start()时,tsn.isAlive() :"+tsn.isAlive()); for(int i=0;i<3;i++) { tsn.printMsg(); } //输出结果是不固定的,true/false System.out.println("main()结束时:"+tsn.isAlive()); } public void run() { for(int i =0;i<3;i++) { printMsg(); } } @SuppressWarnings("static-access") private void printMsg() { // TODO Auto-generated method stub Thread trd = new Thread(); String name = trd.currentThread().getName(); System.out.println("name---"+name); } } 运行结果: 在调用start()之前,tsn.isAlive() :false 在调用start()时,tsn.isAlive() :true name---main name---main name---main main()结束时:true name---test thread name---test thread name---test thread
?4.4后台线程与setDaemon()方法
? ? 1.对java程序来说,只要还有一个前台线程在运行,这个进程就不会结束。
如果一个进程中只有后台线程在运行,这个进程就会结束。
? ? 2.前台线程是相对后台线程而言的,前面所介绍的线程都是前台线程。
? ? 3.后台线程:
? ? ? ? ? 如果某个线程对象在启动(调用start()方法)之前调用了setDaemon(true)方法,
? ? ? 这个线程就变成了后台线程。
?
看一下进程中只有后台线程在运行的情况。
4.4.1代码案例package day34; public class ThreadSetDaemon { public static void main(String[] args) { TestThread ttd = new TestThread(); Thread tt = new Thread(ttd); tt.setDaemon(true);//设置后台运行 tt.start(); } } class TestThread implements Runnable { @Override public void run() { // TODO Auto-generated method stub while(true) { System.out.println(Thread.currentThread().getName()+" is running"); } } } 运行结果: Thread-0 is running Thread-0 is running Thread-0 is running Thread-0 is running ....
?注意:
? ? 从程序和运行结果中:
? ? ? ? 1.创建了一个无限循环的线程,但因为它是后台线程,
? ? ? ? ? 因此整个进程在主线程结束时就随之终止运行了。
? ? ? ? 2.进行中只有后台线程运行时,进程就会结束。
?
4.5线程的强制运行
?
4.5.1 代码案例:
package day34; public class ThreadJoin { public static void main(String[] args) { ThreadJ tj = new ThreadJ(); Thread tr = new Thread(tj); tr.start(); int i =0; for(int k=0;k<6;k++) { if(i == 5) { try { tr.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("main thread :"+(i++)); } } } class ThreadJ implements Runnable { @Override public void run() { // TODO Auto-generated method stub int i = 0; for(int j =0;j<6;j++){ System.out.println(Thread.currentThread().getName()+" "+(i++)); } } } 运行结果: main thread :0 main thread :1 main thread :2 main thread :3 main thread :4 Thread-0 0 Thread-0 1 Thread-0 2 Thread-0 3 Thread-0 4 Thread-0 5 main thread :5
?注意:
? ? 1.本程序两个线程main()和tj线程
? ? 2.调用了tj线程的join()方法,join()是用来强制某一线程的运行。
?
总结:
? ? 1.tj线程中的代码被并入到了main线程中,也就是main线程中的代码等待tj线程执行完。
?
?
4.6 线程的休眠
?
4.6.1代码案例
package day34; public class ThreadSleep extends Thread{ public static void main(String[] args) { ThreadSleep ts = new ThreadSleep(); ts.setName("my worker thread"); ts.start(); try { ts.sleep(700); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }ts.loop(); } @Override public void run() { // TODO Auto-generated method stub loop(); } public void loop() { System.out.println("刚进入loop()方法:"); for(int j =0;j<6;j++){ try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); }System.out.print("离开loop()方法:"); } }
?运行结果:
刚进入loop()方法:
刚进入loop()方法:
my worker thread
main
my worker thread
main
my worker thread
main
my worker thread
main
my worker thread
main
my worker thread
离开loop()方法:main
离开loop()方法:
?
速度慢了很多
?
?
4.7 线程的中断
? ?当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它。
??
未实现
?
?
?
星期日, 十二月 06, 2015 21:45:39
原文:http://yuzhouxiner.iteye.com/blog/2262181