验证 ++ 操作的非原子性

以下示例代码将演示 ++ 操作是非线程安全的,具体看注释的解释,仔细阅读和多次对比执行结果时,也许还能体验到线程被调度执行的随机性,或许对某些读者会有帮助。
还同时对比演示了synchronized关键字的作用----即线程的执行时,需要排队等候调度才行,直到已经获得锁的线程释放此锁,并且自己获得锁才能执行此关键字包含的代码块(或许有点绕)。

package threadpart;

/**
 * 验证 ++ 操作不是原子性的,即多线程下存在安全问题
 * @Author gzx
 * @create 2021-12-30
 */
public class AtomicOrNot {
	public static void main(String[] args) {
		Runnable task=new Runnable() {
			private int i;
			@Override
			public void run() {
//				可以分别单独调用下面这两个私有方法的运行结果分析对比体验一下,同步的作用和 ++操作是否是原子操作(也即是否是多线程安全的),以及所谓的并发场景
				asyn();
//				sync();
			}
//			非同步方法,执行结果随机,因为i++不是线程安全的(我理解为不是原子操作,即这个表达式完成需要取值、算数运算、赋值三步子操作),如果不同步,高并发
//			情况下就会出问题,比如一个线程取得i的值,还没进行运算操作,另外一个线程也取得i的值(第一个线程还未修改过的值),后面具体是哪个线程对i先进行算数运算
//			操作,亦或者对i重新赋值都是不确定的。更何况高并发岂止两个线程呢?
			private void asyn() {
					System.out.println(Thread.currentThread().getName()+"\t"+i++);
			}
//			非同步方法,不过含有synchronized修饰的同步块,所以输出i的值总是固定顺序的,但多次运行时,你会发现,相同的结果不一定由同一线程(指线程名字相同,多次运行,即使线程名相同
//			也不是同一个线程对象啊)得出
			private  void sync() {
					synchronized (this) {
						System.out.println(Thread.currentThread().getName()+"\t"+i++);
					}
			}
		};
		for(int m=0;m<10;m++) {
			new Thread(task, "t"+m).start();
		}
	}
}

和++操作类似的非原子操作有很多,一般都包含了三步操作(取值,远算,赋值),如--,+=,-=等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bitDesigner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值