变量的赋值代码体现为一条语句,但是对应的虚拟机编译后的字节码就可能是多条语句。因此,在多线程环境下,单个变量的赋值可能会出现意想不到的问题。
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);
}
}