java學習筆記--多執行緒

左墾發表於2017-05-25

1.執行緒中存在的現象
1.1執行緒加入public final void jion()
1.2執行緒禮讓public static void yield()
1.3執行緒死亡a. public final void stop();直接結束執行緒,不再做任何操作
b. pubilc void interrupt();結束當前執行緒,並執行完相應的run()方法
使用程式碼對stop()和interrupt()進行測試:

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

public class MyThread extends Thread{
    @Override
    public void run() {
        //列印一下開始執行的時間
        System.out.println("開始時間:"+new SimpleDateFormat("HH:mm:ss").format(new Date()));
        //休眠10秒鐘
        try {
            System.out.println(Thread.interrupted());
            Thread.sleep(10000);
    //      this.interrupt();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();

            System.out.println("我被殺死了");
        }
        System.out.println("結束時間:"+new SimpleDateFormat("HH:mm:ss").format(new Date()));
    }
        public static void main(String[] args) {
        //建立執行緒物件
        MyThread mt = new MyThread();

        //開啟執行緒物件
        mt.start();

        //線上程處於睡眠的過程中將他殺死

        try {
            Thread.sleep(3000);
            //殺死剛剛開啟的執行緒
            //呼叫stop()方法將執行緒直接殺死
            //mt.stop();//劃了一條橫線表示該方法已經過時,但是還可以使用

            //interrupt():直接殺死,在死前,還可以有遺言。
            mt.interrupt();//執行緒被殺死之後會將後面的程式碼執行完畢之後,再死去

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2.執行緒週期
新建,就緒,執行,可能阻塞,死亡執行緒週期
3.執行緒間通訊
以學生設定姓名和年齡為例演示執行緒通訊問題
3.1需要用到的類
Student,SetThread,GetThread,Test
3.2如何使設定和獲取執行緒操作同一物件
建立新的構造器,把資源作為構造引數傳遞下去
3.3使用同步喚醒機制實現執行緒禮讓
3.4實現程式碼

public class Student {
    //塊編輯(alt+shift+a):在使用塊編輯的時候,一定要將輸入法切換到英文輸入法,不然會出問題
    private String name;
    private int age;
    private boolean flag;//在這裡可以作為物件的一個標記,如果是false說明該物件沒有資料,如果是true說明該物件有資料

    //提供公共的方法設定資訊
    public synchronized void setInfo(String name,int age){
        if (this.flag) {
            //等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        //沒有值的話,在這裡給物件設定資料
        this.name = name;
        this.age = age;

        //更改標記,喚醒獲取執行緒獲取資料
        this.flag = true;
        this.notify();
    }
    //提供公共的方法獲取資訊
    public synchronized void getInfo(){
        if (!this.flag) {
            //沒有值
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        //有資料,取資料
        System.out.println(this.name+"--"+this.age);

        //取完資料之後,就沒有資料了
        this.flag = false;
        this.notify();
    }

}
public class SetThread implements Runnable{
    private Student s;
    private int x = 0;

    public SetThread(Student s){
        this.s = s;
    }
    @Override
    public void run() {
        while (true) {
                if (x%2==0) {
                    s.setInfo("劉嘉玲", 50);
                }else {
                    s.setInfo("陳冠希", 35);
                }
                x++;//x=1
            }
    }

}
public class GetThread implements Runnable{
    private Student s;

    public GetThread(Student s){
        this.s = s;
    }

    @Override
    public void run() {
        while (true) {
            s.getInfo();
        }

    }
}
public class StudentDemo {
    public static void main(String[] args) {
        //建立學生物件
        Student s = new Student();
        //建立設定執行緒和獲取執行緒
        SetThread st = new SetThread(s);
        GetThread gt = new GetThread(s);
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(gt);

        //開啟執行緒
        t1.start();
        t2.start();
    }
}

4.執行緒組
4.1定義:java使用ThreadGroup類來表示執行緒組,它可以對一批執行緒進行分類管理,java允許程式直接對執行緒組進行控制,表示一個執行緒的集合,執行緒組構成一棵樹,在樹中,除了初始執行緒組外,每個執行緒組都有一個父執行緒組。允許執行緒訪問有關自己的執行緒組的資訊,但是不允許它訪問有關其執行緒組的父執行緒組或其他任何執行緒組的資訊
4.2獲取執行緒方法
public final ThreadGroup getThreadGroup();獲取執行緒所線上程組
ThreadGroup(String name);建立新的執行緒組
5執行緒池

5.1為什麼要使用執行緒池?

程式啟動一個新執行緒成本是比較高的,因為它涉及到要與作業系統進行互動。而使用執行緒池可以很好的提高效能,
尤其是當程式中要建立大量生存期很短的執行緒時,更應該考慮使用執行緒池。

5.2執行緒池的特點:

執行緒池裡的每一個執行緒程式碼結束後,並不會死亡,而是再次回到執行緒池中成為空閒狀態,等待下一個物件來使用。
在JDK5之前,我們必須手動實現自己的執行緒池,從JDK5開始,Java內建支援執行緒池

5.3執行緒池如何建立?

JDK5新增了一個Executors工廠類來產生執行緒池,有如下幾個方法
public static ExecutorService newFixedThreadPool(inneads)

   5.4執行緒池使用步驟

1.建立執行緒池物件
ExecutorService pool = Executors.newFixedThreadPool(2);

2.建立Runnable例項
MyRunnable my = new MyRunnable();

3.提交Runnable例項
pool.submit(my);
pool.submit(my);

4.關閉執行緒池
pool.shutdown();
6.定時器Timer
一種工具,執行緒用其安排以後在後臺執行緒中執行任務。可安排任務執行一次或定期重複執行。
重要方法:
int purgr();從計時器的任務列表中移除所有已取消的任務。
void schudle(Timer task, Date time);安排在指定的時間執行指定的任務

相關文章