併發背後的問題

栗子的老公發表於2019-01-31

什麼是併發

併發就是指程式同時處理多個任務的能力。
併發程式設計的根源在於對多工情況下對訪問資源的有效控制。

下面來編寫一個執行緒安全與執行緒不安全的例子。
1.執行緒不安全程式碼。
package com.example.demo.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class DownloadsSample {

public static int users=100;        //同時模擬的併發訪問使用者數量
public static int downTotal=50000;  //使用者下載的真實總數
public static int count=0;          //計算器

public static void main(String[] args) {
    //排程器,JDK1.5後提供的concurrent包對於併發的支援
    ExecutorService executorService=Executors.newCachedThreadPool();
    //訊號量,用於模式併發的人數
    final Semaphore semaphore=new Semaphore(users);
    for (int i=0;i<downTotal;i++){
        executorService.execute(()->{
            //通過多執行緒模擬n個使用者併發訪問並下載
            try {
                semaphore.acquire();    //獲取許可
                add();
                semaphore.release();    //釋放許可
            }catch (Exception e){
                e.printStackTrace();
            }
        });
    }
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    executorService.shutdown();     //關閉排程服務
    System.out.println("下載總數:"+count);
}
//執行緒不安全
public static void add(){
    count++;
}

}
2.執行緒安全程式碼。
package com.example.demo.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class DownloadsSample {

public static int users=100;        //同時模擬的併發訪問使用者數量
public static int downTotal=50000;  //使用者下載的真實總數
public static int count=0;          //計算器

public static void main(String[] args) {
    //排程器,JDK1.5後提供的concurrent包對於併發的支援
    ExecutorService executorService=Executors.newCachedThreadPool();
    //訊號量,用於模式併發的人數
    final Semaphore semaphore=new Semaphore(users);
    for (int i=0;i<downTotal;i++){
        executorService.execute(()->{
            //通過多執行緒模擬n個使用者併發訪問並下載
            try {
                semaphore.acquire();    //獲取許可
                add();
                semaphore.release();    //釋放許可
            }catch (Exception e){
                e.printStackTrace();
            }
        });
    }
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    executorService.shutdown();     //關閉排程服務
    System.out.println("下載總數:"+count);
}
//執行緒安全
public synchronized static void add(){
    count++;
}

}

相關文章