執行緒狀態與停止、阻塞(join、yield、sleep)、基本資訊、優先順序JAVA174-177
阿新 • • 發佈:2019-01-08
來源:http://www.bjsxt.com/
一、S02E174_01執行緒狀態與停止執行緒
一、執行緒狀態
新生狀態:用new關鍵字和Thread類或子類建立一個執行緒物件後,該執行緒物件就處於新生狀態。處於新生狀態的執行緒有自己的記憶體空間,通過呼叫start方法進入就緒狀態(Runnable)
就緒狀態:處於就緒狀態的執行緒已經具備了執行條件,但還沒有分配到CPU,處於執行緒就緒佇列,等待系統為其分配CPU。等待狀態並不是執行狀態,當系統選定一個等待執行的Thread物件後,它就會從等待執行狀態進入執行狀態,系統挑選的動作稱之為“CPU排程”。一旦獲得CPU,執行緒就進入執行狀態並自動呼叫自己的run方法
執行狀態:
阻塞狀態:處於執行狀態的執行緒在某些情況下,如執行了sleep(睡眠)方法,或等待I/O裝置等資源,將讓出CPU並暫時停止自己的執行,進入阻塞狀態。在阻塞狀態的執行緒不能進入就緒狀態,只有當引起阻塞的原因消除時,如睡眠時間已到,或等待的I/O裝置空閒下來,執行緒便轉入就緒狀態,重新到就緒佇列中排隊等待,被系統選中後從原來停止的位置開始繼續執行
死亡狀態:死亡狀態是執行緒生命週期中的最後一個階段。執行緒死亡的原因有兩個。一個是正常執行的執行緒完成了它的全部工作;另一個是執行緒被強制性地終止,如通過執行stop或destroy方法來終止一個執行緒(不推薦使用這兩個方法。前者會產生異常,後者是強制終止,不會釋放鎖。)
二、停止執行緒
1、自然終止:執行緒體正常執行完畢
2、外部干涉:
——執行緒類中定義執行緒體使用的標識
——執行緒體使用該標識
——提供對外的方法改變該標識
——外部根據條件呼叫該方法即可
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;
}
}
二、S02E175_01執行緒阻塞1_join_yield
三、S02E176_01執行緒阻塞2_sleep_倒計時_網路延時
1、join:合併執行緒
2、yield:暫停自己的執行緒(static方法,暫停一下,可能下一毫秒又被呼叫,這由CPU決定)
3、sleep:休眠,不釋放鎖
——1)與時間相關:倒計時
——2)模擬網路延時
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;
/**
* 倒計時
* 1、倒數10個數,一秒內列印一個
* 2、倒計時
*/
public class TestSleep {
public static void main(String[] args) throws InterruptedException {
test1();
test2();
}
/**
* 1、倒數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;
}
}
}
/**
* 2、倒計時
* @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);//t1、t2、t3可能都在等待,num可能相同或為-1
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "搶到了" + num--);
}
}
}
四、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();
}
}