Java中使用多線程

Java中關於線程提供了Thread類和Runnable接口,二者都包含run()方法來執行線程,常用的方法列舉如下:

線程的創建和停止

可以通過繼承Thread類來新建一個線程類,也可以通過將類實現Runnable接口來新建。線程擁有name屬性來標識,可以調用setName()方法來設置,也可以在新建Thread對象時調用構造方法傳入字符串爲線程命名。Thread類內可以使用getName()獲取線程的名字,實現Runnable則沒有此方法,可以使用Thread.currentThread().getName()來得到名字。無論是繼承Thread類還是實現Runnable接口,都需要重載run()方法,在run()中定義線程所進行的操作。在創建線程對象之後,通過調用start()方法就會開始執行run()中的內容。

線程的停止不能使用stop()或者interrupt(),而應該在子線程中設置標誌來控制線程的執行。例如在子線程內通過volatile變量來控制子線程的循環,如果需要停止,可以在主進程中訪問該變量,將其設爲false來結束循環。這樣子進程可以繼續執行之後的內容,進行清理工作等,然後結束子進程。

如下所示在主進程首先創建兩個低級別線程thread1、thread2,通過start()啓動後交替執行,每執行一次就會通過yield()讓出處理器,再次進行競爭。之後通過runFlag手動停止兩個低級別線程,然後創建並執行高級別線程highThread。最後等待highThread執行結束後,結束主進程。

//低級進程類
public class LowThread implements Runnable {//通過實現接口來新建線程類
    volatile boolean runFlag = true;     //通過標記來控制循環的執行
    @Override
    public void run() {
        int count = 1;
        String threadName=Thread.currentThread().getName();
        while (runFlag) {
            System.out.println(threadName + "線程循環次數:" + count++);
            Thread.yield();             //每循環一次讓出處理器,重新和其他線程競爭處理器
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(threadName+"執行結束");
    }
}

//高級進程類
public class HighThread extends Thread { //通過繼承Thread類來新建一個線程類

    public void run() {
        System.out.println(getName() + "執行!");    //Thread類內通過getName()獲取線程名
    }
}

//主進程
public class RunThread {
    public static void main(String[] args) throws InterruptedException {
        LowThread thread1Run=new LowThread();   //新建RUnnable對象
        Thread thread1=new Thread(thread1Run,"線程1");        //使用Runnable對象初始化Thread
        thread1.start();                 //線程啓動,自動執行run()方法

        LowThread thread2Run=new LowThread();
        Thread thread2=new Thread(thread2Run,"線程2");
        thread2.start();
        Thread.sleep(50);       //主線程休眠讓出處理器,讓thread1和2使用處理器執行

        System.out.println("高級線程切入");
        thread1Run.runFlag=false;       //在線程外通過volatile變量控制低級線程停止
        thread2Run.runFlag=false;
        HighThread highThread=new HighThread();
        highThread.setName("高級別線程");
        highThread.start();
        highThread.join();          //讓其他線程等待直到高級線程執行結束,否則會先執行主線程,輸出下一句
        System.out.println("主線程執行結束");
    }
}

運行情況如下所示,可以看到在高級進程首先結束,子進程在主進程之後停止,可以做相關清理等工作。

線程互斥和同步

Java通過新建一個Object鎖來控制對於臨界資源的訪問。通過synchronized關鍵字來控制同步,在進入臨界區時首先進行條件判斷,如果滿足則進入,否則將線程放入等待區wait set,之後執行臨界區代碼,執行結束後調用notify()/notifyAll()通知其他進程再次進行資源爭奪。

private final Object lockObj = new Object();

synchronized (lockObj) {

    //進入臨界區的條件判斷
    while (條件) {
        try {
            //條件不滿足, 將當前線程放入Wait Set
            lockObj.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    //執行臨界區代碼
    func();
    
    //喚醒所有在lockObj對象上等待的線程
    lockObj.notifyAll();
}

 

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