實際開發中須要考慮線程安全的場景很常見,日常咱們能夠用定時任務線程池模擬併發安全
線程安全是指在不少請求同時執行時,線程操做的類的數據不會出現錯誤多線程
好比下面這個類併發
public class test { private int a; private int b; public void operate(){ a = a - 1; b = b + 1; System.out.println("當前運行線程:"+Thread.currentThread().getName()+",a與b相加的值若 線程安全則結果一直爲初始值"+(a+b)); } public test(int a,int b){//構造方法 this.a =a; this.b = b; } }
這個類建立的對象有兩個值(a,b) 裏面有一個方法 operate 假設如今有請求調用了這個operate方法若是線程安全的話 那麼打印出來的就一直是構造時傳入a,b值相加,若線程不安全就不必定了(固然這個方法在實際中是不會出現)ide
如今來模擬不少個請求來調用這個方法this
我首先想到的定時任務線程池來模擬線程
public class ServiceTest { public static void main(String[] args) { // TODO Auto-generated method stub test t = new test(100,200); ScheduledExecutorService service = Executors.newScheduledThreadPool(3); service.scheduleAtFixedRate(new MyThread(t), 1, 1,TimeUnit.SECONDS); ScheduledExecutorService service1 = Executors.newScheduledThreadPool(3); service1.scheduleAtFixedRate(new MyThread(t), 1, 2,TimeUnit.SECONDS); ScheduledExecutorService service2 = Executors.newScheduledThreadPool(3); service2.scheduleAtFixedRate(new MyThread(t), 1, 3,TimeUnit.SECONDS); ScheduledExecutorService service3 = Executors.newScheduledThreadPool(3); service3.scheduleAtFixedRate(new MyThread(t), 1, 4,TimeUnit.SECONDS); } } class MyThread implements Runnable{ private test t; public MyThread(test t){ this.t = t; } @Override public void run() { // TODO Auto-generated method stub t.operate(); } }
這裏開了四個 定時任務(ScheduledExecutorService )code
第一個每隔1秒,第二個每隔2秒,第三個每隔3秒,第四個沒隔4秒執行任務對象
所執行的任務就是 test類裏面的operate方法開發
這裏四個定時任務處理的都是同一個對象 test t = new test(100,200);get
多個任務同時處理一個對象纔有可能出現併發問題
最開始operate方法沒加synchronized ,執行一段時間後結果是這樣的
結果中出現了301說明operate方法在多線程併發的狀況下是不安全的
給方法加上synchronized 關鍵字 執行一段時間後結果任然是300這時代碼是線程安全的