JAVA多線程基礎

什麼是線程:
--線程是進程內的執行單元,是進程裏面更小的調度單元
進程的切換是非常重量級的操作

java當中建立了一個線程,會同等的映射到操作系統層面,所以跟操作系統上的線程是等價的


線程的基本操作
新建線程:
Thread t1 = new Thread();             Thread t1 = new Thread();
t1.start();                              t1.run();// 不能開啓線程

Thread.run()的實現target是Runnable接口
public void run() {
    if (target != null) {
        target.run();
    }
}

Thread t1 = new Thread() {
    @Override
    public void run() {
        System.out.println("hello");
    }
}
t1.start();

Thread t1 = new Thread(new CreateThread3());
t1.start();

線程終止:
--Thread.stop() 不推薦使用。它會釋放所有monitor
太暴力,有可能會造成數據的不一致


中斷線程:
一:
public void Thread.interrupt()  //中斷線程
public boolean Thread.isInterrupted()  //判斷是否被中斷
public static boolean Thread.isInterrupted()  //判斷是否被中斷,並清除當前中斷狀態

public void run() {
    while(true) {
        Thread.yield();
    }
}

t1.interrupt();// 打個招呼,告訴你這個線程要中斷了

// 優雅的對線程進行中斷,操作結束後才進行中斷,不會造成數據不一致問題
public void run() {
    while(true) {
        if (Thread.currentThread().isInterrupted()) {
            System.out.println("Interrupted");
            break;
        }
        Thread.yield();
    }
}

二:
public static native void sleep(long millis) throws InterruptedException

public void run() {
    while(true) {
        if (Thread.currentThread().isInterrupted()) {
            System.out.println("Interrupted");
            break;
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException) {
            System.out.println("interrupted When Sleep");
            // 設置中斷狀態,拋出異常後會清除中斷標誌
            Thread.currentThread.interrupt();
        }
        Thread.yield();
    }
}


掛起(suspend)和繼續執行(resume)進程:
--suspend()不會釋放所
--如果加鎖發生在resume()之前,則死鎖發生


等待線程結束(join)和謙讓(yeild):
public final void join() throws InterruptedException
public final synchronized void join(long millis) throws InterruptedException

public class JoinMain{
    public volatile static int i = 0;
    public static class AddThread extends Thread{
        @Override
        public void run() {
            for (i = 0; i < 10000000; i++) {
            
            }
        }
    }
    
    public static void main(String[] args) throws InterruptedException{
        AddThread at = new AddThread();
        at.start();
        at.join();
        System.out.println(i);
    }
}

join的本質
while (isAlive()) {// 判斷線程是否結束
    wait(0);// 讓當前線程等待
}
線程執行完畢後,系統會調用notifyAll(),喚醒所有等待在當前線程上的所有線程

不要在Thread實例上使用wait()和notify()方法


守護線程:
--在後臺默默的完成一些系統性的服務,比如垃圾回收線程、JIT線程就可以理解爲守護線程
--當一個java應用內,只有守護線程時,java虛擬機就會自然退出

Thread t = new Thread();
t.setDaemon(true);// 將線程設置爲守護線程,要在開啓線程之前設置,否則會報非法異常
t.start();


線程優先級:
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

Thread high = new HightPriority();
Thread low = new LowPriority();
high.setPriority(Thread.MAX_PRIORITY);
low.setPriority(Thread.MIN_PRIORITY);
low.start();
hight.start();
高優先級的線程更容易在競爭中獲勝

基本的線程同步操作
一:
synchronized:
--直接加鎖對象:對給定對象加鎖,進入同步代碼前要獲得給定對象的鎖。
--直接作用於實例方法:相當於對當前實例加鎖,進入同步代碼前要獲得當前實例的鎖。
--直接作用於靜態方法:相當於對當前類加鎖,進入同步代碼前要獲得當前類的鎖。

synchronized是java內置的,所有的實現是在java虛擬機內部實現的,所有操作都是在虛擬機內部進行的

二:
Object.wait()  Object.notify()

wait()調用前必須要獲得當前線程的監視器,調用後會釋放當前線程的監視器
notify()調用前必須要先獲得當前線程的監視器

notify:隨機喚醒等待在當前線程上的一個線程
notifyAll:喚醒等待在當前線程上的所有線程
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章