码迷,mamicode.com
首页 > 编程语言 > 详细

Java线程状态、线程停止、线程阻塞

时间:2015-05-28 09:31:11      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:阻塞   线程   

线程状态(五种状态)

技术分享

Java 线程的生命周期包括创建,就绪,运行,阻塞,死亡5 个状态。一个 Java 线程总是处于这 5 个生命周期状态之一,并在一定条件下可以在不同状态之间进行转换 。

创建状态 (New Thread)
在 Java 语言中使用 new操作符创建一个线程后,该线程仅仅是一个空对象,它具备了线程的一些特征,但此时系统没有为其分配资源,这时的线程处于创建状态。

就绪状态 (Runnable)
使用 start()方法启动一个线程后,系统为该线程分配了除 CPU 外的所需资源,使该线程处于就绪状态。此外,如果某个线程执行了 yield() 方法,那么该线程会被暂时剥夺 CPU 资源,重新进入就绪状态。

运行状态 (Running)
Java运行系统通过调度选中一个处于就绪状态的线程,使其占有 CPU 并转为运行状态。此时,系统真正执行线程的 run() 方法。

阻塞状态 (Blocked)
一个正在运行的线程因某些原因不能继续运行时,它就进入阻塞状态。
这些原因包括:当执行了某个线程对象的suspend()、sleep()等阻塞类型的方法时,该线程对象会被置入一个阻塞集(Blocked Pool)内,等待被唤醒(执行 resume()方法)或是因为超时而时自动苏醒;
当多个线程试图进入某个同步区域(synchronized)时,没能进入该同步区域的线程会被置入锁定集(Lock Pool),直到获得该同步区域的锁,进入就绪状态;
当线程执行了某个对象的 wait() 方法时,线程会被置入该对象的等待集(Wait Pool)中,直到执行了该对象的 notify()方法,wait()/notify()方法的执行要求线程首先获取到该对象的锁。

死亡状态 (Dead)
线程在 run() 方法执行结束后进入死亡状态。此外,如果线程执行了 interrupt()stop() 方法,那么它也会以异常退出的方式进入死亡状态。

停止线程(两种方式)

1、自然终止:线程体正常执行完毕
2、外部干涉

1)线程类中 定义线程体使用的标识。
2)线程体使用该标识。
3)提供对外的方法,改变该标识。
4) 外部根据条件调用该方法即可

注意:避免使用Thread类自己提供的stop()(具有不安全性)、suspend()(具有固有的死锁现象)、resume() 等方法

package Threadstate;

/**
 * 停止线程
 * @author liguodong
 */
public class Demo01 {
    public static void main(String[] args) {
        Study s = new Study();
        new Thread(s).start();//启动
        //外部干涉
        for(int i=0;i<100;i++)
        {
            if(50==i)//外部干涉(并不是非常准确,还要看CPU)
            {
                s.stop();
            }
            System.out.println("main....-->"+i);
        }
    }   
}

class Study implements Runnable
{
    //1、线程类中,定义线程体使用的标识
    private boolean flag = true;    
    @Override
    public void run() {
        //2、线程体使用该标识
        while(flag)
        {
            System.out.println("Study thread....");
        }       
    }
    //3、对外提供方法改变标识
    public void stop()
    {
        this.flag = false;
    }
}

线程阻塞

1、join:合并线程
2、yield:暂停自己的线程 static方法
3、sleep:指定的毫秒数内让当前正在执行的线程休眠(暂停执行),不会释放锁。
(1)与时间相关,如倒计时
(2)模拟网络延时

package Threadstate;

/**
 * 线程阻塞: join合并线程   
 */
public class Demo02 extends Thread{

    @Override
    public void run() {
        for(int i=0;i<100;i++)
        {
                System.out.println("join..."+i);            
        }   
    }   
    public static void main(String[] args) throws InterruptedException {

        Demo02 demo = new Demo02();
        Thread t = new Thread(demo);//新生
        t.start();//就绪
        //cpu调度运行       
        for(int i=0;i<100;i++)
        {
            if(50==i)
            {
                t.join();//main阻塞
            }
            System.out.println("main..."+i);                
        }
    }
}
package Threadstate;
/**
 * yield:暂停自己的线程   static方法
 * @author liguodong
 */
public class Demo03 extends Thread{
    public static void main(String[] args) {
        Demo03 demo = new Demo03(); 
        Thread t  = new Thread(demo);//新生
        t.start();//就绪
        //cpu调度运行       
        for(int i=0; i<1000; i++)
        {
            if(i%20==0)
            {
                //在main线程中,暂停本线程main   
                //本方法写在那个线程体里面就停止那个线程,如果在run里面暂停 Demo03。
                Thread.yield();//静态方法(并没有严格意义上的暂停,可能CPU又调度到它)
            }
            System.out.println("main..."+i);
        }

    }   
    @Override
    public void run() {
        for(int i=0; i<1000; i++)
        {   
            System.out.println("yield..."+i);
        }
    }
}
package Threadstate;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * sleep:指定的毫秒数内让当前正在执行的线程**休眠**(暂停执行),不会释放锁。
 * 倒计时
 * 1、倒数十个数,1秒内打印一个
 * 2、倒计时
 */
public class Demo04 {
    public static void main(String[] args) throws InterruptedException
    {       
        //test01();
        test02();   
    }   
    //倒数十个数,1秒内打印一个
    public static void test01() throws InterruptedException
    {
        int num = 10;
        while(true)
        {
            System.out.println(num--);
            Thread.sleep(1000);//暂停
            if(num<=0)
            {
                break;
            }
        }
    }

    //倒计时
    public static void test02() throws InterruptedException
    {
        //new Date()当前时间   System.currentTimeMillis()也表示当前时间
        Date endTime = new Date(System.currentTimeMillis()+10*1000);//当前时间往后10秒
        long end = endTime.getTime();//获取结束时间的长整型
        while(true)
        {
            //输出
            System.out.println(new SimpleDateFormat("HH:mm:ss").format(endTime));
            //构建下一秒的时间
            endTime = new Date(endTime.getTime()-1000);//减一秒  endTime依次递减
            //等待1秒
            Thread.sleep(1000);//暂停
            //10秒以内继续   否则退出 end-10000当前时间  
            if(end-10000>endTime.getTime())
            {
                break;
            }
        }   
    }       
}
package Threadstate;

/**
 * sleep模拟网络延时  线程不安全的类   结果可能不准确
 */
public class Demo05 {
    public static void main(String[] args) {
        //真实角色
        Web12306 web = new Web12306();
        //代理
        Thread t1 = new Thread(web,"德玛西亚");
        Thread t2 = new Thread(web,"卡特琳娜");
        Thread t3 = new Thread(web,"德邦总管");
        //启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

class Web12306 implements Runnable{
    private int num = 50;
    @Override
    public void run() {
        while(true)
        {
            if(num<=0)
            {
                break;//跳出循环
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"抢到了倒数第"+num--+"张");            
        }
    }
}

Java线程状态、线程停止、线程阻塞

标签:阻塞   线程   

原文地址:http://blog.csdn.net/scgaliguodong123_/article/details/46049573

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!