java原子變數
阿新 • • 發佈:2019-02-16
變數的賦值程式碼體現為一條語句,但是對應的虛擬機器編譯後的位元組碼就可能是多條語句。因此,在多執行緒環境下,單個變數的賦值可能會出現意想不到的問題。
java5後增加了“原子變數”的概念,目前支援的“原子變數”有AtomicInteger、AtomicLong、Integer和Long的“原子陣列”變數AtomicIntegerArray和AtomicLongArray。
這些原子變數實現的原理是被稱為“CAS”操作的方法實現的。根據統計使用原子變數解決執行緒安全問題的效能優於使用“鎖”。
我分別寫了兩套程式去驗證,雖然使用Integer沒有驗證出問題,但是並不排除。
定義Company類,Company中有AtomicInteger型別的account變數,一個執行緒預設將account遞增1000.
定義User類,User中也有AtomicInteger型別的accout變數,對應於Company,一個執行緒預設將account遞減1000。
測試方法分別起動1000個執行緒,account的初始值為1000,看最終的結果來判斷。
package com.z; import java.util.concurrent.atomic.AtomicInteger; public class Company implements Runnable{ private AtomicInteger count; public Company(AtomicInteger count){ this.count = count; } @Override public void run(){ for(int i = 0; i < 1000; i ++){ count.getAndIncrement(); } } }
package com.z; import java.util.concurrent.atomic.AtomicInteger; public class User implements Runnable { private AtomicInteger count; public User(AtomicInteger count){ this.count = count; } @Override public void run() { for(int i = 0; i < 1000; i ++) count.getAndDecrement(); } }
package com.z;
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
public static void main(String[] args){
for(int i = 1; i <= 100; i ++){
System.out.println(" 第"+i+"次執行");
count();
}
}
public static void count(){
AtomicInteger oriCount = new AtomicInteger(1000);
int COMPANY_NUM = 1000;
int USER_NUM = 1000;
Thread[] company = new Thread[COMPANY_NUM];
Thread[] user = new Thread[USER_NUM];
for(int i = 0; i < COMPANY_NUM; i ++){
company[i] = new Thread(new Company(oriCount));
company[i].start();
}
for(int i = 0; i < USER_NUM; i ++){
user[i] = new Thread(new User(oriCount));
user[i].start();
}
try {
for(int i = 0; i < COMPANY_NUM; i ++)
company[i].join();
for(int i = 0; i < USER_NUM; i ++)
user[i].join();
} catch (InterruptedException e) {
System.out.println("company or user join() is fail");
}
System.out.println("最終計算結果是:" + oriCount.get());
}
}
Integer測試,對照以上程式碼:
package com.z;
public class LowCompany implements Runnable{
private Integer count;
public LowCompany(Integer count){
this.count = count;
}
@Override
public void run(){
for(int i = 0; i < 1000; i ++){
count++;
}
}
}
package com.z;
public class LowUser implements Runnable {
private Integer count;
public LowUser(Integer count){
this.count = count;
}
@Override
public void run() {
for(int i = 0; i < 1000; i ++)
count--;
}
}
package com.z;
public class LowTest {
public static void main(String[] args){
for(int i = 1; i <= 1000; i ++){
System.out.println(" 第"+i+"次執行");
count();
}
}
public static void count(){
Integer oriCount = new Integer(1000);
int COMPANY_NUM = 1000;
int USER_NUM = 1000;
Thread[] company = new Thread[COMPANY_NUM];
Thread[] user = new Thread[USER_NUM];
for(int i = 0; i < COMPANY_NUM; i ++){
company[i] = new Thread(new LowCompany(oriCount));
company[i].start();
}
for(int i = 0; i < USER_NUM; i ++){
user[i] = new Thread(new LowUser(oriCount));
user[i].start();
}
try {
for(int i = 0; i < COMPANY_NUM; i ++)
company[i].join();
for(int i = 0; i < USER_NUM; i ++)
user[i].join();
} catch (InterruptedException e) {
System.out.println("company or user join() is fail");
}
System.out.println("最終計算結果是:" + oriCount);
}
}