java---教你怎么判斷多線程是否安全


多線程不安全,主要因為cpu分配機制,誰獲得了cpu誰就能執行,因此造成了線程的不安全.

那么,如何找出問題呢?

1.明確哪些代碼是多線程運行的代碼,
2.明確共享數據
3.明確多線程運行代碼中哪些語句是操作共享數據.

根據以上三部.下面看例子,

package com.niuli.develop;

public class Test {
    public static void main (String [] args) {
        Cus c = new Cus();
        new Thread(c).start();
        new Thread(c).start();
    }
}

class Bank{
    private int sum = 0;
    public void add(int n) {
        sum = sum + n;
        System.out.println("sum= "+sum);
    }
}

class Cus implements Runnable{
    Bank b = new Bank();
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            b.add(100);
        }
    }
}

很簡單的例子,
首先第一步,找到多線程運行的代碼

也就是run方法里面的代碼
for (int i = 0; i < 3; i++) {
            b.add(100);
        }
        另外這里用到了Add方法,所以add也算
 public void add(int n) {
        sum = sum + n;
        System.out.println("sum= "+sum);
    }

第二步,找到共享數據

Bank b = new Bank();
private int sum = 0;

第三步,明確多線程使用的共享數據.
首先對於數據b就一條語句使用了這個共享變量,因此不會出現線程不安全,但是對於sum,有兩條語句使用的,所以就會出現線程安全問題,

解決辦法,同步塊

Object obj = new Object();
    public void add(int n) {
        synchronized (obj) {
            sum = sum + n;
            System.out.println("sum= "+sum);
        }
    }

或者,同步函數

public synchronized void add(int n) {
            sum = sum + n;
            System.out.println("sum= "+sum);
    }

以上就是線程安全的解決辦法,同步機制雖然游俠,但是帶來了一定的性能損耗,所以,對操作共享數據的部分執行同步,盡量減少這種損耗

補充:

如果同步函數是靜態的,那么使用的鎖就必須是所在類的字節碼文件對象,也就是 類名.class,解釋來說,靜態是和類一起加載的,所以在靜態加載的時候是不可能有object的對象,所以鎖就必須用在靜態加在之前的一個對象.

版權聲明:本文為博主原創文章,未經博主允許不得轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM