您的位置:首页 > 编程语言 > Java开发

Java并发控制synchronized与AtomicInteger类

2016-11-14 16:28 337 查看
众所周知,在Java多线程编程中,一个非常重要的方面就是线程的同步问题。关于线程的同步,最常用的解决方法就是使用synchronized关键字,但是如果使用场景只用在控制一个计数的整型变量时(通常这也是非常常见的一个使用场景),另一种实现方式AtomicInteger类简洁易用的特性一定会让你对它爱不释手。
我们先通过一个简单的例子模拟下多线程并发计数,程序如下
public class ShareData {
public static int count=0;
public static void main(String[] args){
final ShareData data  = new ShareData();
for(int i=0;i<10;i++){
new Thread(
new Runnable(){
public void run(){
try{
Thread.sleep(1);
}catch(InterruptedException e){
e.printStackTrace();
}
for(int j=0;j<100;j++){
data.addCount();
}
System.out.print(count+" ");
}
}
).start();
}
try{
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.print("count="+count);
}
public void addCount(){
count++;
}
}


程序启动了十个线程,每个线程计100次数,操作的都是count这个变量,最后在等待3秒(所有线程均执行结束后)输出此时的count值,每次执行后的输出结果都不一定一样,但是一般count小于1000,结果如下:

100 224 373 473 373 255 823 791 691 591 count=823

344 566 366 299 299 466 366 669 695 769 count=769

400 400 400 500 400 615 913 813 713 713 count=913

我们将addCount()方法加上synchronized关键词修饰下,让它实现线程安全,

public synchronized void addCount(){
count++;
}

再执行,结果如下:

200 200 411 677 774 864 1000 666 1000 891 count=1000

423 909 1000 428 802 512 691 706 512 914 count=1000

300 500 500 300 300 712 809 850 949 1000 count=1000

此时可以看出最终count的数值都会精确的是1000,讲完了synchronized之后我们再来看下AtomicInteger类

AtomicInteger类可以用原子方式更新的
int 值,主要用于在高并发环境下的高效程序处理,使用非阻塞算法来实现并发控制,它的方法有

//获取当前的值
public final int get()
//取当前的值,并设置新的值
public final int getAndSet(int newValue)
//获取当前的值,并自增
public final int getAndIncrement()
//获取当前的值,并自减
public final int getAndDecrement()
//获取当前的值,并加上预期的值
public final int getAndAdd(int delta)
这里我们依然用上面的程序做例子,使用AtomicInteger类来替代synchronized方式,代码如下:
package concurrent;

import java.util.concurrent.atomic.AtomicInteger;

public class ShareData_AtomicInteger {
static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args){
final ShareData_AtomicInteger data = new ShareData_AtomicInteger();
for(int i=0;i<10;i++){
new Thread(
new Runnable(){
public void run(){
try{
Thread.sleep(1);
}catch(InterruptedException e){
e.printStackTrace();
}
for(int j=0;j<100;j++){
data.addCount();
}
System.out.print(count.get()+" ");
}
}
).start();
}
try{
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.print("count="+count.get());
}
public void addCount(){
count.getAndIncrement();
}
}





执行结果如下:

495 528 604 504 987 657 741 682
1000 925 count=1000

500 500 984 823 499 733 500 495
601 1000 count=1000

409 409 436 409 700
587 600 872 988 1000 count=1000

至此结束,AtomicInteger只是concurrent下的一个整数原子操作类,该包下还有很多其他关于线程锁同步的机制,有兴趣的同学可以自行搜索下相关资料~谢谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息