标签:
线程的生命周期

由上图可以看出:
线程的状态转换是线程控制的基础。线程状态总的可分为五大状态:分别是生、死、可运行、运行、等待/阻塞。
各个状态细节不再赘述,具体请看http://blog.csdn.net/u011225629/article/details/46288995此篇博文
此篇博文主要讲述各个状态的实例!
一、新建和就绪状态
此处不做细致的讲解,在上一篇博文中已经讲解过了!
package com.haixu.thread2;
public class InvokeRun extends Thread{
/*
* 新建就绪状态练习
* 通过继承Thread类来创建线程
* */
private int i;
public void run(){
for(; i<5; i++){
//直接调用run()方法是,Thread的this.getName()返回的是该对象的名字
//使用Thread.currentThread().getName()调用当前线程获取线程名字
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args) {
for(int i=0; i<4; i++){
//使用Thread.currentThread().getName()调用当前线程获取线程名字
System.out.println(Thread.currentThread().getName() + " " + i);
if(i == 3){
new InvokeRun().start();
//直接调用线程对象的run()方法
new InvokeRun().run();
new InvokeRun().start();
}
}
}
}
堵塞状态是前述四种状态中最有趣的,值得我们作进一步的探讨。线程被堵塞可能是由下述五方面的原因造成的:
(1) 调用sleep(毫秒数),使线程进入“睡眠”状态。在规定的时间内,这个线程是不会运行的。
(2) 用suspend()暂停了线程的执行。除非线程收到resume()消息,否则不会返回“可运行”状态。
(3) 用wait()暂停了线程的执行。除非线程收到nofify()或者notifyAll()消息,否则不会变成“可运行”(是的,这看起来同原因2非常相象,但有一个明显的区别是我们马上要揭示的)。
(4) 线程正在等候一些IO(输入输出)操作完成。
(5) 线程试图调用另一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。
解决上面的堵塞,让线程重新进入就绪状态:
1、调用sleep()方法的的线程经过的指定的时间。
2、线程调用的阻塞式IO方法返回、
3、线程成功的获得了试图取得的同步监视器。
4、线程正在等待某个通知,其他线程发出了一个通知。
5、处于挂起状态的线程被调用了resume()恢复方法。
/**
* 一个计数器,计数到100,在每个数字之间暂停1秒,每隔10个数字输出一个字符串
*
* @author leizhimin 2008-9-14 9:53:49
*/
public class MyThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
if ((i) % 10 == 0) {
System.out.println("-------" + i);
}
System.out.print(i);
try {
Thread.sleep(1);
System.out.print(" 线程睡眠1毫秒!\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new MyThread().start();
}
}
package com.haixu.thread2;
import java.util.Date;
public class SleepTest {
public static void main(String[] args) throws Exception{
for( int i=0; i<5; i++){
System.out.println("当前的时间:" + new Date());
Thread.sleep(1000);
}
}
}
运行结果:
当前的时间:Sun May 31 17:59:25 CST 2015 当前的时间:Sun May 31 17:59:26 CST 2015 当前的时间:Sun May 31 17:59:27 CST 2015 当前的时间:Sun May 31 17:59:28 CST 2015 当前的时间:Sun May 31 17:59:29 CST 2015
2、线程的优先级和线程让步yield()
package com.haixu.thread2;
/*
* 使用Yield对线程让步,是正在执行的线程停止
*
*/
public class YieldTest extends Thread{
public YieldTest(String name){
super(name);
}
//定义run()作为执行体
public void run(){
for( int i=0; i<6; i++){
System.out.println(getName() + " " + i);
//当i=4时线程做出让步
if(i==4){
Thread.yield();
}
}
}
public static void main(String[] args) {
//启动两个并发线程
YieldTest yt = new YieldTest("高级");
yt.setPriority(Thread.MAX_PRIORITY);
yt.start();
//将此线程设置成低权限
YieldTest yt1 = new YieldTest("低级");
yt1.setPriority(Thread.MIN_PRIORITY);
yt1.start();
}
}
高级 0 高级 1 高级 2 高级 3 低级 0 低级 1 低级 2 低级 3 高级 4 高级 5 低级 4 低级 5
package com.haixu.thread2;
/*
* 当调用其他线程的join方法时,调用线程被阻塞
* 直到被join方法加入的线程执行完为止
*
*/
public class JoinTest extends Thread{
//提供有参数的构造器,用于设置线程的名称
public JoinTest(String name){
super(name);
}
public void run(){
for(int i = 0; i<6; i++){
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) throws InterruptedException {
//启动子线程
new JoinTest("新线程").start();
for(int i=0; i< 5; i++){
if(i == 2){
JoinTest jt = new JoinTest("被Join的线程");
jt.start();
//main线程调用了jt线程的join方法,main线程
//必须等jt之行结束才会向下执行
jt.join();
}
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
执行结果:
main 0 main 1 新线程 0 新线程 1 新线程 2 新线程 3 新线程 4 新线程 5 被Join的线程 0 被Join的线程 1 被Join的线程 2 被Join的线程 3 被Join的线程 4 被Join的线程 5 main 2 main 3 main 4
疯狂Java学习笔记(64)------------线程转换
标签:
原文地址:http://blog.csdn.net/u011225629/article/details/46289431