1、S02E174_01线程状态与中止线程
1、线程状态
新生状态:用new关键字和Thread类或子类创建一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有本身的内存空间,经过调用start方法进入就绪状态(Runnable)
就绪状态:处于就绪状态的线程已经具有了运行条件,但尚未分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并非执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动做称之为“CPU调度”。一旦得到CPU,线程就进入运行状态并自动调用本身的run方法
运行状态:在运行状态的线程执行本身的run方法中代码,直到调用其它方法而终止、或等待某资源而阻塞或完成任务而死亡。若是在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态。
阻塞状态:处于运行状态的线程在某些状况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时中止本身的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪状态,只有当引发阻塞的缘由消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,从新到就绪队列中排队等待,被系统选中后从原来中止的位置开始继续运行
死亡状态:死亡状态是线程生命周期中的最后一个阶段。线程死亡的缘由有两个。一个是正常运行的线程完成了它的所有工做;另外一个是线程被强制性地终止,如经过执行stop或destroy方法来终止一个线程(不推荐使用这两个方法。前者会产生异常,后者是强制终止,不会释放锁。)
2、中止线程
一、天然终止:线程体正常执行完毕
二、外部干涉:
——线程类中定义线程体使用的标识
——线程体使用该标识
——提供对外的方法改变该标识
——外部根据条件调用该方法便可java
package com.test.thread.status; public class TestStatus { public static void main(String[] args) { Study s = new Study(); new Thread(s).start(); //外部干涉 for (int i = 0; i < 100000; i++) { if(50000 == i){//外部干涉 s.stop(); System.out.println("stop...-->>" + i); } } } } class Study implements Runnable{ //线程类中定义线程体使用的标识 private boolean flag = true; @Override public void run() { //线程体使用该标识 while(flag){ System.out.println("study thread..."); } } //对外提供方法改变标识 public void stop(){ this.flag = false; } }
3、S02E176_01线程阻塞2_sleep_倒计时_网络延时
一、join:合并线程
二、yield:暂停本身的线程(static方法,暂停一下,可能下一毫秒又被调用,这由CPU决定)
三、sleep:休眠,不释放锁
——1)与时间相关:倒计时
——2)模拟网络延时web
package com.test.thread.status; /** * join:合并线程 */ public class TestJoin extends Thread { public static void main(String[] args) throws InterruptedException { TestJoin testJoin = new TestJoin(); Thread t = new Thread(testJoin);//新生状态 t.start();//就绪状态 //CPU调度 运行 for (int i = 0; i < 1000; i++) { if(50==i){ t.join();//main阻塞,等待t执行完 } System.out.println("main..."+i); } } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("join..."+i); } } }
package com.test.thread.status; /** * yield:暂停本身的线程(static方法,暂停一下,可能下一毫秒又被调用,这由CPU决定) */ public class TestYield extends Thread { public static void main(String[] args) { TestYield testYield = new TestYield(); Thread t = new Thread(testYield); t.start(); for (int i = 0; i < 1000; i++) { if(0==i%200){ //暂停当前线程 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 com.test.thread.status; import java.text.SimpleDateFormat; import java.util.Date; /** * 倒计时 * 一、倒数10个数,一秒内打印一个 * 二、倒计时 */ public class TestSleep { public static void main(String[] args) throws InterruptedException { test1(); test2(); } /** * 一、倒数10个数,一秒内打印一个 * @throws InterruptedException */ public static void test1() throws InterruptedException{ int num = 10; while(true){ System.out.println(num--); Thread.sleep(1000);//暂停 if(num <= 0){ break; } } } /** * 二、倒计时 * @throws InterruptedException */ public static void test2() throws InterruptedException{ Date endTime = new Date(System.currentTimeMillis() + 10*1000); long end = endTime.getTime(); while(true){ //输出 System.out.println(new SimpleDateFormat("mm:ss").format(endTime)); //等待一秒 Thread.sleep(1000); //构建下一秒时间 endTime = new Date(endTime.getTime() - 1000); //10秒之内继续,不然退出 if(end-10000 > endTime.getTime()){ break; } } } }
package com.test.thread.status; /** * sleep模拟网络延时 * 引发并发问题 ... 路人甲抢到了44 攻城狮抢到了44 ... 路人甲抢到了1 攻城狮抢到了0 黄牛乙抢到了-1 */ public class TestSleep2 { 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;//1到50号 @Override public void run(){ while(true) { if(num <= 0){ break;//跳出循环 } try { Thread.sleep(500);//t一、t二、t3可能都在等待,num可能相同或为-1 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "抢到了" + num--); } } }
4、S02E177_01线程基本信息_优先级
网络
package com.test.thread.info; public class MyThread implements Runnable { private boolean flag = true; private int num = 0; @Override public void run() { while(flag){ System.out.println(Thread.currentThread().getName()+ "-->>" + num++); } } public void stop(){ flag = !flag; } }
package com.test.thread.info; /** * Thread.currentThread * setName() * getName() * isAlive */ public class InfoDemo { public static void main(String[] args) throws InterruptedException { MyThread it = new MyThread(); Thread proxy = new Thread(it,"挨踢"); proxy.setName("test"); System.out.println(proxy.getName()); System.out.println(Thread.currentThread().getName());//main proxy.start(); System.out.println("启动后的状态:" + proxy.isAlive()); Thread.sleep(50); it.stop(); Thread.sleep(100);//stop后,CPU不必定当即中止,休眠一下看一下效果 System.out.println("中止后的状态:" + proxy.isAlive()); } }
package com.test.thread.info; /** * 优先级:几率,不是绝对的前后顺序 * MAX_PRIORITY 10 * NORM_PRIORITY 5(默认) * MIN_PRIORITY 0 * * setPriority() * getPriority() */ public class InfoPriority { public static void main(String[] args) throws InterruptedException { MyThread it1 = new MyThread(); Thread p1 = new Thread(it1,"挨踢1"); MyThread it2 = new MyThread(); Thread p2 = new Thread(it2,"挨踢2"); p1.setPriority(Thread.MIN_PRIORITY); p2.setPriority(Thread.MAX_PRIORITY); p1.start(); p2.start(); Thread.sleep(100); it1.stop(); it2.stop(); } }