问题分析:正如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方式实现。

Java-JUC(十三):现在有两个线程同时操作一个整数I,做自增操作,如何实现I的线程安全性?的更多相关文章

  1. Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。

    精彩理解:  https://www.jianshu.com/p/21be831e851e ;  https://blog.csdn.net/heyutao007/article/details/19 ...

  2. Java中如何把两个数组合并为一个

    在Java中,如何把两个String[]合并为一个? 看起来是一个很简单的问题.但是如何才能把代码写得高效简洁,却还是值得思考的.这里介绍四种方法,请参考选用. 一.apache-commons 这是 ...

  3. Java实现把两个数组合并为一个的方法总结

    本文实例讲述了Java实现把两个数组合并为一个的方法.分享给大家供大家参考,具体如下: 在Java中,如何把两个String[]合并为一个? 看起来是一个很简单的问题.但是如何才能把代码写得高效简洁, ...

  4. java 写一个"HelloJavaWorld你好世界"输出到操作系统文件Hello.txt文件中

    package com.beiwo.homework; import java.io.File; import java.io.FileOutputStream; import java.io.IOE ...

  5. Java反射机制demo(六)—获得并操作一个类的属性

    Java反射机制demo(六)—获得并操作一个类的属性 获得并操作一个类的属性?! 不可思议啊,一个类的属性一般都是私有成员变量啊,private修饰符啊! 但是毫无疑问,这些东西在Java的反射机制 ...

  6. Java - "JUC线程池" ThreadPoolExecutor原理解析

    Java多线程系列--“JUC线程池”02之 线程池原理(一) ThreadPoolExecutor简介 ThreadPoolExecutor是线程池类.对于线程池,可以通俗的将它理解为"存 ...

  7. Java - "JUC线程池" 线程状态与拒绝策略源码分析

    Java多线程系列--“JUC线程池”04之 线程池原理(三) 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基本概念"中,我们介绍过,线程有5种状态:新建 ...

  8. Java - "JUC" ReentrantLock获取锁

    [Java并发编程实战]-----“J.U.C”:ReentrantLock之一简介 ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”. 顾名思义,R ...

  9. Java - "JUC"之Condition源码解析

    Java多线程系列--“JUC锁”06之 Condition条件 概要 前面对JUC包中的锁的原理进行了介绍,本章会JUC中对与锁经常配合使用的Condition进行介绍,内容包括:Condition ...

随机推荐

  1. oracle 如何预估将要创建的索引的大小

    一.1  oracle 如何预估将要创建的索引的大小 oracle 提供了2种可以预估将要创建的索引大小的办法: ①  利用包 Dbms_space.create_index_cost 直接得到 ②  ...

  2. PHP提示 Notice: Undefined variable

    PHP提示Notice: Undefined variable,意思是:你的程序中有未定义的变量 为什么在其他地方好好的程序,换个环境报这个Notice,因为php.ini提醒级别设置的问题 场景复原 ...

  3. 二、Linux_系统信息查看

    系统信息查看 1. Linux查看cpu核数等信息: [root@tdh01 ~]# grep 'physical id' /proc/cpuinfo | sort -u # 查看物理cpu个数 ph ...

  4. influxDB应用及TICK stack

    InfluxData平台用于处理度量和事件的时间序列平台,常被称为TICK stack,包含4个组件:Telegraf,influxDB,Chronograf和Kapacitor,分别负责时间序列数据 ...

  5. while 格式化输出 运算符 字符编码

    流程控制之while循环 条件循环:while,语法如下 while 条件: # 循环体 # 如果条件为真,那么循环体则执行,执行完毕后再次循环,重新判断条件... # 如果条件为假,那么循环体不执行 ...

  6. C语言强、弱符号,强、弱引用

    C语言强.弱符号,强.弱引用 符号定义 在编程中我们经常碰到符号重复定义的情况,当我们在同一个作用域内重复定义同一个变量时,有时是因为误写,有时是文件之间的冲突,编译器的处理方式就是报错: redef ...

  7. python使用print写文件

    刚刚看sumo的官方教程,有一段代码是生成配置文件,发现python中的print函数也可以写文件. with open("data/cross.rou.xml", "w ...

  8. C# 退出应用程序的几种方法

    Application.Exit();//好像只在主线程可以起作用,而且当有线程,或是阻塞方法的情况下,很容易失灵 this.Close();//只是关闭当前窗体. Application.ExitT ...

  9. LOJ#2343. 「JOI 2016 Final」集邮比赛 2

    题目地址 https://loj.ac/problem/2343 题解 首先处理出\(f[i]\)表示以当前位置开头(J,O,I)的合法方案数.这个显然可以\(O(n)\)处理出来.然后考虑在每个位置 ...

  10. Python开发应用-操作excel

    一. openpyxl读 95%的时间使用的是这个模块,目前excel处理的模块,只有这个还在维护 1.workBook workBook=openpyxl.load_workbook('path(. ...