线程安全之如何实现多线程下的自增安全
2017-05-21 19:05
239 查看
package com.ilucky.test.jdk.util.concurrent; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; /** * 线程安全: 当多个线程访问某个类时, 这个类始终都能表现出正确的行为, 那么就称这个类是线程安全的。 * @author IluckySi * */ public class ThreadSafeTest { public static int count = 0; public static Counter counter = new Counter(); public static AtomicInteger atomicInteger = new AtomicInteger(0); volatile public static int countVolatile = 0; public static void main(String[] args) { // 保证所有线程执行完毕. final CountDownLatch cdl = new CountDownLatch(10); for(int i=0; i<10; i++) { new Thread() { public void run() { for (int j = 0; j < 1000; j++) { count++; counter.increment(); atomicInteger.getAndIncrement(); countVolatile++; } cdl.countDown(); } }.start(); } try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("static count: " + count); System.out.println("Counter: " + counter.getValue()); System.out.println("AtomicInteger: " + atomicInteger.intValue()); System.out.println("countVolatile: " + countVolatile); } } class Counter { private int value; public synchronized int getValue() { return value; } public synchronized int increment() { return value++; } public synchronized int decrement() { return --value; } } /** 运行结果如下,每次运行结果都不一样,但是每次中间的两个都是10000. static count: 9997 Counter: 10000 AtomicInteger: 10000 countVolatile: 9997 说明要解决自增操作在多线程环境下线程不安全的问题,可以选择使用Java提供的原子类或者使用synchronized同步方法。 而使用volatile关键字, 并不能解决非原子操作的线程安全性。 另外: 虽然递增操作++i看上去只是一个操作, 但这个操作并非原子的, 因而它并不会作为一个不可分割的操作来执行。 实际上它包含了三个独立的操作: 读取count的值, 将值加1, 然后将计算结果写入count. 这是一个“读取 - 修改 - 写入”的操作序列, 并且其结果状态依赖于之前的状态。 补充: volatile变量具有synchronized的可见性特性, 但是不具备原子特性。 volatile变量可用于提供线程安全, 但是应用场景非常局限: 多个变量之间或者某个变量的当前值与修改后值之间没有约束。 因此, 单独使用volatile还不足以实现计数器、互斥锁或任何具有与多个变量相关的不变式. */
相关文章推荐
- boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。
- 拿来主义:java中的线程安全与非线程安全,以及如何使用和实现
- 黑马程序员——java第十一、十二天:多线程(创建线程1-2、多线程同步代码、实现Runnable接口、安全死锁)
- 如何正确实现多线程安全的singleton patterns
- 多线程系列八:线程安全、Java内存模型(JMM)、底层实现原理
- c# winform下使用多线程时在线程里如何安全访问窗体控件InvokeRequired
- boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。
- java多线程有几种实现方法?线程之间如何同步
- C# Winform项目中多线程环境下, 如何跨线程对Window窗体控件进行安全访问?
- 线程和进程的区别?以及如何实现多线程
- servlet如何实现多线程安全??
- 0019 Servlet容器的实现:单实例多线程的线程安全问题【基础】
- JAVA基础再回首(二十四)——多线程的概述、实现方式、线程控制、生命周期、多线程程序练习、安全问题的解决
- java如何实现线程的安全:线程的同步机制
- 多线程简单实现与线程安全问题的简单处理
- java基础—HashMap实现原理,如何保证HashMap的线程安全?
- 黑马程序员-(多线程)了解线程与如何解决线程同步到来的安全问题!(面试)
- 黑马程序员——多线程之线程安全的实现详解
- servlet如何实现多线程安全??
- 在Servlet和JSP中如何实现多线程安全