【java多線程1】進程,線程,線程實現方式的概述

一.進程與線程

進程:是代碼在數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位

線程:是進程中的一個執行路徑,是cpu分配的基本單位。一個進程最少擁有一個線程。

二. Java多線程的創建及啓動

1.繼承Thread類

優點獲取當前線程簡單直接使用this即可,缺點java不支持多繼承,繼承了Thread就無法繼承其他類了。

public class MyThread extends Thread {
    
    private int i = 0;

    @Override
    public void run() {
        for (i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}



public class ThreadTest {

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                // 創建一個新的線程  myThread1  此線程進入新建狀態
                Thread myThread1 = new MyThread();
                // 創建一個新的線程 myThread2 此線程進入新建狀態
                Thread myThread2 = new MyThread();  
                // 調用start()方法使得線程進入就緒狀態   
                myThread1.start();
                // 調用start()方法使得線程進入就緒狀態                     
                myThread2.start();                     
            }
        }
    }
}

2.實現Runnable接口

 優點接口可以多實現,減少耦合

public class MyRunnable implements Runnable {
    private int i = 0;

    @Override
    public void run() {
        for (i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}



public class ThreadTest {

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                // 創建一個Runnable實現類的對象
                Runnable myRunnable = new MyRunnable(); 
                // 將myRunnable作爲Thread target創建新的線程
                Thread thread1 = new Thread(myRunnable); 
                Thread thread2 = new Thread(myRunnable);
                // 調用start()方法使得線程進入就緒狀態
                thread1.start(); 
                thread2.start();
            }
        }
    }
}

說明: 繼承Thread類與實現Runnable接口創建線程方式相似,不同的地方在於,因爲Thread類本身也是實現了Runnable接口。

/**Thread類中對Runnable接口中run()方法的實現*/
@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

也就是說,當執行到Thread類中的run()方法時,會首先判斷target是否存在,存在則執行target中的run()方法,也就是實現了Runnable接口並重寫了run()方法的類中的run()方法  

3.使用Callable接口和FutureTask類創建線程

優點是具有返回值 

public class MyCallable implements Callable<Integer> {
    private int i = 0;

    // 與run()方法不同的是,call()方法具有返回值
    @Override
    public Integer call() {
        int sum = 0;
        for (; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            sum += i;
        }
        return sum;
    }

}



public class ThreadTest {

    public static void main(String[] args) {
        // 創建MyCallable對象
        Callable<Integer> myCallable = new MyCallable();    
        // 使用FutureTask來包裝MyCallable對象
        FutureTask<Integer> ft = new FutureTask<Integer>(myCallable); 

        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                // FutureTask對象作爲Thread對象的target創建新的線程
                Thread thread = new Thread(ft);
                // 線程進入到就緒狀態   
                thread.start();                      
            }
        }

        System.out.println("主線程for循環執行完畢..");
        
        try {
            // 取得新創建的新線程中的call()方法返回的結果
            int sum = ft.get();            
            System.out.println("sum = " + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

需要特別注意的是:不能對同一線程對象兩次調用start()方法。原因是threadStatus的在一次調用後值就變化了,再次進入的時候通過判斷threadStatus的值從而產生異常。

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