線程安全-001

例子程序:安全

/** * 多個線程一把鎖 * @author dev * */
public class MyThread extends Thread{ private int count = 5; //synchronized
 @Override public void run() { count--; System.err.println(this.currentThread().getName() + " count = "+count); } public static void main(String[] args) { /** * 多個線程訪問myThread的run方法時,以排隊的方式進行處理(CPU分配的前後順序排隊) * 一個線程想要執行synchronized修飾的方法裏的代碼: * 1,嘗試得到鎖 * 2,若是拿到該鎖,執行synchronized代碼體內容,拿不到鎖,這個線程就會不斷嘗試得到這把鎖, * 直到拿到未止,並且是多個線程同時去競爭這把鎖(也就是有鎖競爭的問題) * */ MyThread myThread = new MyThread(); //參數:Runnable target, String name
        Thread t1 = new Thread(myThread,"t1"); Thread t2 = new Thread(myThread,"t2"); Thread t3 = new Thread(myThread,"t3"); Thread t4 = new Thread(myThread,"t4"); Thread t5 = new Thread(myThread,"t5"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } }
代碼說明:
MyThread繼承Thread,是一個線程類,有一成員變量count,重寫run方法:對count值進行減減,打印當前線程名字和count值。
main方法:啓動5個線程t一、t二、t三、t四、t5,把MyThread對象注入進去,啓動5個線程。

執行main方法,結果:

   線程啓動後,5個線程都等待着cpu的執行,因此5個線程的執行順序是隨機的,致使看到的t一、t2 、t三、 t四、 t5的輸出順序是隨機的。對於count值,咱們內心預期的應該輸出 count=四、count=三、count=二、count=一、count=0,可是輸出結果跟心理預期的是不同的。這就是說,5個線程同時訪問MyThread類的run方法,對count值進行減減,不是線程安全的。多線程

將run方法加上synchronized 關鍵字,就是線程安全的:ide

//synchronized加鎖
    @Override
    public synchronized void run() {
        count--;
        System.err.println(this.currentThread().getName() + " count = "+count);
    }

打印結果:this

這和咱們內心的預期是同樣的,也就是線程安全的。這就和開篇說的線程安全的定義:當多個線程訪問某一個類(對象或者方法)時,這個類始終都能表現出正確的行爲,那麼這個類(對象或方法)就是線程安全的。這裏的正確的行爲,就是指你內心預期的。spa

 run方法 加上synchronized加鎖後,啓動5個線程,當第一個線程拿到鎖後,其餘4個線程就會等待,等着第一個線程釋放鎖,一次類推。線程

多線程就是一個廁所,廁所門上有一個鎖,外面5我的去搶這一把鎖,誰搶到了鎖,就能夠進去上廁所,當第一個進去的出來後,其餘4我的會同時去搶這把鎖。因此會產生鎖競爭的問題,當線程足夠多的時候,鎖競爭會致使CPU使用率太高,應儘可能避免鎖競爭。3d

 搞10000個線程,看看鎖競爭cpu使用狀況:code

代碼:對象

MyThread myThread = new MyThread();
        List<Thread> threads = new ArrayList<Thread>();
        for(int i=0;i<10000;i++){
            threads.add(new Thread(myThread,"t"+i)); 
        }
        for(Thread t : threads){
            t.start();
        }

CPU:blog

相關文章
相關標籤/搜索