Java-JUC(十三):现在有两个线程同时操作一个整数I,做自增操作,如何实现I的线程安全性?
问题分析:正如i在多线程中如果想实现i的多线程操作,必须i要使用volitle来保证其内存可见性,但是i++自增操作不具备原子性操作,因此需要对i++这段代码确保其原子性操作即可。
方案1:
使用ReetranLock实现i++的原子性操作。
private static volatile int i=0; public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch=new CountDownLatch(2); Lock lock=new ReentrantLock(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { try{ lock.lock(); i++; }finally{ lock.unlock(); countDownLatch.countDown(); } } },"Thread-1"); Thread thread2 = new Thread(new Runnable() { @Override public void run() { try{ lock.lock(); i++; }finally{ lock.unlock(); countDownLatch.countDown(); } } },"Thread-2"); thread1.start(); thread2.start(); countDownLatch.await(); System.out.println(i); }
方案2:
使用Semaphore实现i++的原子性操作。
private static volatile int i = 0; public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(2); Semaphore semaphore = new Semaphore(1); Thread thread1 = new Thread(new Runnable() { @Override public void run() { try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } i++; semaphore.release(); countDownLatch.countDown(); } }, "Thread-1"); Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } i++; semaphore.release(); countDownLatch.countDown(); } }, "Thread-2"); thread1.start(); thread2.start(); countDownLatch.await(); System.out.println(i); }
当然也可以选择sychronized方式实现。
基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
【+加关注】。