星期日, 十二月 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