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

多線程不安全,主要由於cpu分配機制,誰得到了cpu誰就能執行,所以形成了線程的不安全.安全

那麼,如何找出問題呢?markdown

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

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

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,有兩條語句使用的,因此就會出現線程安全問題,spa

解決辦法,同步塊線程

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

或者,同步函數code

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

以上就是線程安全的解決辦法,同步機制雖然遊俠,可是帶來了必定的性能損耗,因此,對操做共享數據的部分執行同步,儘可能減小這種損耗對象

補充:

若是同步函數是靜態的,那麼使用的鎖就必須是所在類的字節碼文件對象,也就是 類名.class,解釋來講,靜態是和類一塊兒加載的,因此在靜態加載的時候是不可能有object的對象,因此鎖就必須用在靜態加在以前的一個對象.

相關文章
相關標籤/搜索