java多線程


多線程

優(yōu)點: 解決一個進程同時執(zhí)行多個代碼任務(wù)的問題


自定義線程

方法1: 繼承Thread

  1. 自定義一個雷繼承Thread
  2. 重寫Threadrun()方法,多線程代碼在run()中執(zhí)行
  3. 創(chuàng)建Thread子類對象,并調(diào)用start()方法啟動一個線程.
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }
    }
}
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(super.getName() + i);
        }
    }

Console

main0
Thread-00
main1
Thread-01
main2
Thread-02
main3

方法2: 實現(xiàn)Runnable接口

  1. 自定義一個類implements Runnable接口
  2. 實現(xiàn)Runnable接口中的run()方法,把自定義線程的任務(wù)代碼定義在run()方法中
  3. 創(chuàng)建Runnable實現(xiàn)類的對象
  4. 創(chuàng)建Thread對象,并把Runnable實現(xiàn)類的對象作為參數(shù)傳遞
  5. 調(diào)用Thread對象的start()方法開啟線程
public static void main(String[] args) {
        //MyThread myThread = new MyThread();
        //myThread.start();
        MyThread2  myThread2 = new MyThread2();
        Thread th = new Thread(myThread2);
        th.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }
    }
class MyThread2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }   
    }
}

Console

main0
Thread-00
main1
Thread-01
main2
Thread-02


線程安全

弊端:多個線程需要判斷鎖,較為消耗資源

線程安全出現(xiàn)問題原因:

1.必須存在兩個或以上的線程共享著一個資源.
2.操作共享資源的代碼必須有兩句或者兩句以上.

1.同步代碼塊

synchronized(對象){//這個對象可以是任意對象
//需要被同步的代碼
//對象如同鎖,持有鎖的線程可以在同步中執(zhí)行 
//沒持有鎖的線程即使獲取CPU的執(zhí)行權(quán),也進不去 
}
    public static void main(String[] args) {
        //MyThread myThread = new MyThread();
        //myThread.start();
        MyThread2  myThread2 = new MyThread2();
        Thread th1 = new Thread(myThread2);
        Thread th2 = new Thread(myThread2);
        Thread th3 = new Thread(myThread2);
        Thread th4 = new Thread(myThread2);
        th1.start();
        th2.start();
        th3.start();
        th4.start();
    }
class MyThread2 implements Runnable{
    Object obj = new Object();
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            synchronized (obj) {
                System.out.println(Thread.currentThread().getName() +","+ i);
            }
            
        }   
    }
}

Console

Thread-0,0
Thread-0,1
Thread-0,2
Thread-2,0
Thread-2,1
Thread-2,2
Thread-1,0
Thread-1,1
Thread-1,2
Thread-3,0
Thread-3,1
Thread-3,2

2.同步函數(shù)

修飾符 synchronized 返回值類型 函數(shù)名(形參列表...){
}
class Bank{
    private int sum = 0;
    public synchronized void add(int a){//同步函數(shù)
        sum += a;
        try{
            Thread.sleep(40);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("sum = " + sum);
    }
}
class Client implements Runnable{
    private Bank b = new Bank();
    @Override
    public void run(){
        for (int i = 0; i < 3; i++) {
            b.add(100);
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        Client c = new Client();
        Thread t1 = new Thread(c);  
        Thread t2 = new Thread(c);  

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

注意 :

  1. 同步代碼的鎖,可以是任意對象Object,同步函數(shù)的鎖,是固定的,非靜態(tài)函數(shù)的鎖對象是this ,靜態(tài)函數(shù)的鎖對象是class對象
  2. 同步鎖對象必須是多線程共享的對象,否則鎖不住(鎖唯一)
  3. 再同步代碼塊或者同步函數(shù)中調(diào)用sleep方法不會釋放鎖對象,調(diào)用 wait方法是會釋放對象的。

給個github follow me的鏈接,上面有很多初學者可供學習的資料,項目.

<a>https://github.com/SuperZee</a>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容