[Java] Thread -- 避免Race Condition (Synchronized)

 

public class TestRaceCondition implements Runnable{

    public static int counter = 0;

    public static void main(String[] args) {

        List<Thread> threads = new ArrayList<>();
        //產生threads,加入ArrayList
        for( int i=0 ; i < 10 ; i++) {
            TestRaceCondition runnable = new TestRaceCondition();
            Thread t1 = new Thread(runnable,"T"+i);
            threads.add(t1);
        }
        //一起發動所有的thread
        for (Thread thread : threads) {
            thread.start();
        }
        try {
            //main thread 等待所有執行緒結束
            for (Thread thread : threads) {
                thread.join();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //印出最後的值
        System.out.println("finally counter = "+counter);

    }

    @Override
    public void run() {
        for ( int i= 0  ; i < 1000 ;i ++){
            incrementCounter();
        }
    }

    public static  void incrementCounter(){   
        counter = counter + 1;
    }

}

 

[原始程式架構]

設立10個執行序塞入List中,再同時執行程序,各自生成一個Runnable的物件,執行run(),再incrementCounter()

此處會有共搶的Race Condtion發生,避免此狀況,可使用synchronized管控程序

(%所有synchronized標的都需唯一)

 

1. static 方法 加上 synchronized

所有用到這個方法的都是受到管控的,鎖頭為類別自身(TestRaceCondition.class)  

 public static synchronized void incrementCounter(){  
        counter = counter + 1;
    }

 

2.方法中設立專鎖物件控管執行方法

    //設立專鎖物件
    public  final static Object locker = new Object(); 
    
    @Override
    public void run() {
        for ( int i= 0  ; i < 1000 ;i ++){
            synchronized (TestRaceCondition.locker)
            incrementCounter();
        }
    }

 

3. 一般方法中加上 synchronized

所有用到這個方法的都是受到管控的,鎖頭為自身物件()

但此處每個Thread都各自生成物件執行程式,所以不具管控性,需調整程式為 => 生成一個執行物件,所有程序都使用同一物件

public static void main(String[] args) {
.
.
        List<Thread> threads = new ArrayList<>();
        TestRaceCondition runnable = new TestRaceCondition();
        for( int i=0 ; i < 10 ; i++) {
            Thread t1 = new Thread(runnable,"T"+i);
            threads.add(t1);
.
.

    @Override
    public synchronized void run() {
        for ( int i= 0  ; i < 1000 ;i ++){
            incrementCounter();
        }
    }

 

上一篇:mysql工具类日志(binlog、slowlog、errorlog)


下一篇:Redis慢日志查询