1. 程式人生 > >執行緒常用操作方法

執行緒常用操作方法

執行緒常用操作方法
取得和設定執行緒的名稱
1.在Threadl類中,可以通過getName()方法取得執行緒的名稱,通過setName()方法設定執行緒的名稱
2.執行緒的名稱一般在啟動執行緒前設定,但也允許為已經執行的執行緒設定名稱。允許兩個Thread物件有相同的名字,但為了清晰,應儘量避免這種情況的發生
3.另外,如果程式並沒有為執行緒指定名稱,則系統會自動的為執行緒分配一個名稱。

public class ThreadNameDemo {
public static void main(String[] args) {
MyThread mt = new MyThread(); //例項化Runnable子類物件
new Thread(mt).start(); //系統自動設定執行緒名稱
new Thread(mt,”執行緒A”).start(); //手工設定執行緒名稱
new Thread(mt,”執行緒B”).start(); //手工設定執行緒名稱
new Thread(mt).start(); //系統自動設定執行緒名稱
new Thread(mt).start(); //系統自動設定執行緒名稱
}
}

class MyThread implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
for(int i = 0;i < 3;i++) {
System.out.println(Thread.currentThread().getName() + “執行,i = ” + i);
}
}
}
程式執行效果:
Thread-0執行,i = 0
執行緒B執行,i = 0
執行緒B執行,i = 1
執行緒B執行,i = 2
執行緒A執行,i = 0
執行緒A執行,i = 1
Thread-0執行,i = 1
Thread-0執行,i = 2
Thread-2執行,i = 0
Thread-2執行,i = 1
執行緒A執行,i = 2
Thread-1執行,i = 0
Thread-2執行,i = 2
Thread-1執行,i = 1
Thread-1執行,i = 2

從執行效果來看.制定的名稱會自動出現,如果沒有指定會發現執行緒使用自動編號的方式完成。按照:Thread-0,Thread-1依次編號,實際上肯定在類中存在一個static屬性,用於記錄編號

當前執行緒
程式可以通過currentThread()方法取得當前正在執行的程式物件

public class CurrentThreadDemo {
public static void main(String[] args) {
    MyThread mt = new MyThread();  //例項化Runnable子類物件
    new Thread(mt,"執行緒").start();  //啟動執行緒
    mt.run();   //直接呼叫run()方法

}

}

class MyThread01 implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
for(int i = 0;i < 3;i++) {
System.out.println(Thread.currentThread().getName() + “執行,i = ” + i);
}
}
程式執行結果:
main執行,i = 0
執行緒執行,i = 0
main執行,i = 1
執行緒執行,i = 1
main執行,i = 2
執行緒執行,i = 2
此時發現,程式中由主方法直接通過執行緒物件呼叫裡面的run()方法,所以輸出的結果中包含了一個“main”,此執行緒就是由“mt.run()”,因為呼叫此語句是由主方法完成的,也就是說實際上主方法本身也是一個執行緒–主執行緒

問題:既然主方法都是以執行緒的形式出現的,那麼java執行時到底啟動了多少個執行緒呢
回答:至少兩個
從之前學習到的知識來看,每當java程式執行的時候,實際上都會啟動一個jvm,每一個jvm實際上就是作業系統中啟動了一個程序。java中本身具備了垃圾收集機制,所以java執行時至少啟動了兩個執行緒:主執行緒,GC(垃圾回收機制)

判斷執行緒是否啟動
public class ThreadAliveDemo {
public static void main(String[] args) {
MyThread02 mt = new MyThread02(); //例項化Runnable子類物件
Thread t = new Thread(mt,”執行緒”); //例項化Thread物件
System.out.println(“執行緒開始之前–>” + t.isAlive()); //判斷是否啟動
t.start(); //啟動執行緒
System.out.println(“執行緒開始之後–>” + t.isAlive());
for(int i = 0;i < 3;i++) {
System.out.println(“main執行–>” + i);
}
System.out.println(“程式碼執行之後–>” + t.isAlive());

}

}

class MyThread02 implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
for(int i = 0;i < 3;i++) {
System.out.println(Thread.currentThread().getName() + “執行,i = ” + i);
}
}
}
執行結果:執行緒開始之前–>false
執行緒開始之後–>true
main執行–>0
main執行–>1
main執行–>2
程式碼執行之後–>true

執行緒的強制執行
線上程操作中,可以使用join()方法讓一個執行緒強制執行,執行緒強制執行期間,其他執行緒無法執行,必須等待此執行緒完成之後才可以繼續執行

public class ThreadJoinDemo {
public static void main(String[] args) {
MyThread03 mt = new MyThread03(); //例項化Runnable子類物件
Thread t = new Thread(mt,”執行緒”); //例項化Thread物件

    t.start(); //啟動執行緒

    for(int i = 0;i < 50;i++) {
        if(i>10) {
            try {
                t.join();
            }catch(InterruptedException e) {}
        }
            System.out.println("Main執行緒執行 -->" + i);
        }
    }

}

class MyThread03 implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
for(int i = 0;i < 50;i++) {
System.out.println(Thread.currentThread().getName() + “執行,i = ” + i);
}
}
}
程式執行結果:
Main執行緒執行 –>0
執行緒執行,i = 0
Main執行緒執行 –>1
執行緒執行,i = 1
Main執行緒執行 –>2
Main執行緒執行 –>3
Main執行緒執行 –>4
Main執行緒執行 –>5
Main執行緒執行 –>6
Main執行緒執行 –>7
Main執行緒執行 –>8
Main執行緒執行 –>9
執行緒執行,i = 2
Main執行緒執行 –>10
執行緒執行,i = 3
執行緒執行,i = 4
執行緒執行,i = 5
執行緒執行,i = 6
執行緒執行,i = 7
執行緒執行,i = 8
執行緒執行,i = 9
執行緒執行,i = 10
執行緒執行,i = 11
執行緒執行,i = 12
執行緒執行,i = 13
執行緒執行,i = 14
執行緒執行,i = 15
執行緒執行,i = 16
執行緒執行,i = 17
執行緒執行,i = 18
執行緒執行,i = 19
執行緒執行,i = 20
執行緒執行,i = 21
執行緒執行,i = 22
執行緒執行,i = 23
執行緒執行,i = 24
執行緒執行,i = 25
執行緒執行,i = 26
執行緒執行,i = 27
執行緒執行,i = 28
執行緒執行,i = 29
執行緒執行,i = 30
執行緒執行,i = 31
執行緒執行,i = 32
執行緒執行,i = 33
執行緒執行,i = 34
執行緒執行,i = 35
執行緒執行,i = 36
執行緒執行,i = 37
執行緒執行,i = 38
執行緒執行,i = 39
執行緒執行,i = 40
執行緒執行,i = 41
執行緒執行,i = 42
執行緒執行,i = 43
執行緒執行,i = 44
執行緒執行,i = 45
執行緒執行,i = 46
執行緒執行,i = 47
執行緒執行,i = 48
執行緒執行,i = 49
Main執行緒執行 –>11
Main執行緒執行 –>12
Main執行緒執行 –>13
Main執行緒執行 –>14
Main執行緒執行 –>15
Main執行緒執行 –>16
Main執行緒執行 –>17
Main執行緒執行 –>18
Main執行緒執行 –>19
Main執行緒執行 –>20
Main執行緒執行 –>21
Main執行緒執行 –>22
Main執行緒執行 –>23
Main執行緒執行 –>24
Main執行緒執行 –>25
Main執行緒執行 –>26
Main執行緒執行 –>27
Main執行緒執行 –>28
Main執行緒執行 –>29
Main執行緒執行 –>30
Main執行緒執行 –>31
Main執行緒執行 –>32
Main執行緒執行 –>33
Main執行緒執行 –>34
Main執行緒執行 –>35
Main執行緒執行 –>36
Main執行緒執行 –>37
Main執行緒執行 –>38
Main執行緒執行 –>39
Main執行緒執行 –>40
Main執行緒執行 –>41
Main執行緒執行 –>42
Main執行緒執行 –>43
Main執行緒執行 –>44
Main執行緒執行 –>45
Main執行緒執行 –>46
Main執行緒執行 –>47
Main執行緒執行 –>48
Main執行緒執行 –>49

執行緒的休眠
在程式中允許一個執行緒進行暫時的休眠,直接使用Thread.sleep()方法即可
public class ThreadSleepDemo {
public static void main(String[] args) {
MyThread04 mt = new MyThread04(); //例項化Runnable子類物件
Thread t = new Thread(mt,”執行緒”); //例項化Thread物件

    t.start(); //啟動執行緒

}

}

class MyThread04 implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
for(int i = 0;i < 50;i++) {
try {
Thread.sleep(500);
}catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + “執行,i = ” + i);
}
}
}

執行緒的中斷
當一個執行緒執行的時候,另外一個執行緒可以直接通過interrupt()方法,中斷其執行狀態
public class ThreadInterruptDemo {
public static void main(String[] args) {
MyThread05 mt = new MyThread05(); //例項化Runnable子類物件
Thread t = new Thread(mt,”執行緒”); //例項化Thread物件

    t.start(); //啟動執行緒
    try {
        Thread.sleep(10000);    

    }catch(InterruptedException e) {
        System.out.println("3.休眠被終止");
    }
    t.interrupt();//中斷執行緒執行

}

}

class MyThread05 implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
System.out.println(“1.進入run()方法”);

        try {
            Thread.sleep(2000);   
            System.out.println("2.已經完成休眠");
        }catch(InterruptedException e) {
            System.out.println("3.休眠被終止");
            return ;   //返回呼叫處;
        }
        System.out.println("4.run方法正常結束");
    }
}

後臺執行緒
在java中,只要一個程式沒有執行完成(一個執行緒在執行),則整個java進行不會消失,所以此時可以設定一個後臺執行緒,這樣即使java程序結束了,則後臺執行緒依然會繼續執行

public class ThreadDaemonDemo {
public static void main(String[] args) {
MyThread06 mt = new MyThread06(); //例項化Runnable子類物件
Thread t = new Thread(mt,”執行緒”); //例項化Thread物件

    t.setDaemon(true);  //執行緒在後臺執行
    t.start();              //啟動執行緒
}

}

class MyThread06 implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
while(true) {
System.out.println(Thread.currentThread().getName() + “在執行”);
}
}

執行緒的優先順序
在java的執行緒操作中,所有的執行緒在執行前都會保持就緒狀態,那麼此時,誰的優先順序高,那個執行緒就有可能被先執行
最高優先順序:MAX_PRIORTY
中等優先順序:NORM_PRIORTY
最低優先順序:MIN_PRIORTY

public class ThreadPriorityDemo {
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread07(),”執行緒A”);
Thread t2 = new Thread(new MyThread07(),”執行緒B”);
Thread t3 = new Thread(new MyThread07(),”執行緒C”);

    t1.setPriority(Thread.MIN_PRIORITY);
    t2.setPriority(Thread.MAX_PRIORITY);
    t3.setPriority(Thread.NORM_PRIORITY);

    t1.start();
    t2.start();
    t3.start();
}

}

class MyThread07 implements Runnable{ //實現Runnable介面
public void run() { //覆寫run方法
for(int i = 0;i < 5;i++) {
try {
Thread.sleep(500);
}catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + “執行,i = ” + i);
}
}
}
執行結果:
執行緒B執行,i = 0
執行緒C執行,i = 0
執行緒A執行,i = 0
執行緒B執行,i = 1
執行緒C執行,i = 1
執行緒A執行,i = 1
執行緒B執行,i = 2
執行緒C執行,i = 2
執行緒A執行,i = 2
執行緒B執行,i = 3
執行緒C執行,i = 3
執行緒A執行,i = 3
執行緒B執行,i = 4
執行緒C執行,i = 4
執行緒A執行,i = 4

主方法優先順序
public class MainPriorityDemo {
public static void main(String args[]) {
System.out.println(“主方法優先順序:” + Thread.currentThread().getPriority()); //取得主方法優先順序
System.out.println(“MAX_PRIORITY = ” + Thread.MAX_PRIORITY);
System.out.println(“MIN_PRIORITY = ” + Thread.MIN_PRIORITY);
System.out.println(“NORM_PRIORITY = ” + Thread.NORM_PRIORITY);
}
}

執行結果:
主方法優先順序:5
MAX_PRIORITY = 10
MIN_PRIORITY = 1
NORM_PRIORITY = 5

執行緒禮讓
public class ThreadYieldDemo {
public static void main(String[] args) {
MyThread10 my = new MyThread10();

    Thread t1 = new Thread(my,"執行緒A");
    Thread t2 = new Thread(my,"執行緒B");

    t1.start();
    t2.start();
}

}

class MyThread10 implements Runnable{
public void run() {
for(int i = 0;i < 5;i++) {
try {
Thread.sleep(500);
}catch(Exception e){}
System.out.println(Thread.currentThread().getName() + “執行,i = ” + i);
if(i == 2) {
System.out.println(“執行緒禮讓”);
Thread.currentThread().yield();
}
}
}
}
執行結果:
執行緒A執行,i = 0
執行緒B執行,i = 0
執行緒A執行,i = 1
執行緒B執行,i = 1
執行緒A執行,i = 2
執行緒B執行,i = 2
執行緒禮讓
執行緒禮讓
執行緒B執行,i = 3
執行緒A執行,i = 3
執行緒B執行,i = 4
執行緒A執行,i = 4

總結
在本章中重點只是闡述了執行緒的基本操作方法。對於這些操作,實際上都是從Thread類中找出來的,用的時候只需要查詢Thread類即可
對於休眠的操作最好記住,因為以後還要用

例項要求
要求:設計一個執行緒的操作類,要求可以產生三個執行緒物件,並可以設定三個執行緒的休眠時間,如下所示:
執行緒A休眠10秒
執行緒B休眠20秒
執行緒C休眠30秒

使用Thread類完成

public class ThreadSleep {
public static void main(String[] args) {
MyThread123 t1 = new MyThread123(“執行緒A”,10000);
MyThread123 t2 = new MyThread123(“執行緒B”,20000);
MyThread123 t3 = new MyThread123(“執行緒C”,30000);

    t1.start();
    t2.start();
    t3.start();

}

}

class MyThread123 extends Thread{
private int time;

public MyThread123(String name,int time) {
    super(name);   //設定執行緒名稱
    this.time = time;   //設定休眠時間
}

public void run() {
    try {
        Thread.sleep(this.time);   //指定休眠時間
    }catch(InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "執行緒,休眠" + this.time + "毫秒");
}

}
執行結果:
執行緒A執行緒,休眠10000毫秒
執行緒B執行緒,休眠20000毫秒
執行緒C執行緒,休眠30000毫秒

使用Runnable介面
如果使用Runnable介面,則類中是沒有執行緒名稱存在的,所以應該單獨建立一個name屬性,以保證執行緒名稱的存在

public class RunnableSleep {
public static void main(String[] args) {
MyThread010 mt1 = new MyThread010(“執行緒A”,10000);
MyThread010 mt2 = new MyThread010(“執行緒B”,20000);
MyThread010 mt3 = new MyThread010(“執行緒C”,30000);

    new Thread(mt1).start();
    new Thread(mt2).start();
    new Thread(mt3).start();


}

}

class MyThread010 implements Runnable{
private String name;
private int time;

public MyThread010(String name,int time) {
    this.name = name;
    this.time = time;
}
public void run() {
    try {
        Thread.sleep(this.time);
    }catch(InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(this.name + "執行緒,休眠" + this.time + "毫秒");
}

}
執行結果:
執行緒A執行緒,休眠10000毫秒
執行緒B執行緒,休眠20000毫秒
執行緒C執行緒,休眠30000毫秒