Java并发编程之如何保证原子性(一)

首先说什么是并发?

并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力。
如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善。
现代的PC都有多个CPU或一个CPU中有多个核。是否能合理运用多核的能力将成为一个大规模应用程序的关键。
进程与线程
进程是以独立于其他进程的方式运行的,进程间是互相隔离的。一个进程无法直接访问另一个进程的数据。
进程的资源诸如内存和CPU时间片都是由操作系统来分配。

线程又被称为轻量级进程。每个线程有它独自的调用栈, 但是在同一进程下的线程又能互相访问它们间的共享数据。
每个线程都有它独自的缓存。如果一个线程读取了某些共享数据,那么它将这些数据存放在自己的缓存中以供将来再次读取。

一个JAVA应用程序默认以一个进程的形式运行着。在一个JAVA程序中,你将协同多个不同的线程一起完成并行运算或实现异步行为。
并发编程需要解决的三特性和三问题

三种性质

可见性:一个线程对共享变量的修改,另一个线程能立刻看到。缓存可导致可见性问题。
原子性:一个或多个CPU执行操作不被中断。线程切换可导致原子性问题。
有序性:编译器优化可能导致指令顺序发生改变。编译器优化可能导致有序性问题。

三个问题
安全性问题:线程安全
活跃性问题:死锁、活锁、饥饿
性能问题:
使用无锁结构:TLS,Copy-On-Write,乐观锁;Java的原子类,Disruptor无锁队列
减少锁的持有时间:让锁细粒度。如ConcurrentHashmap;再如读写锁,读无锁写有锁

Java内存模型

volatile

C语言中的原意:禁用CPU缓存,从内存中读出和写入。
Java语言的引申义:
Java会将变量立刻写入内存,其他线程读取时直接从内存读(普通变量改变后,什么时候写入内存是不一定的)
禁止指令重排序
解决问题:
保证可见性
保证有序性
不能保证原子性
Happens-Before规则(H-B)
程序顺序性规则:前面执行的语句对后面语句可见
volatile变量规则:volatile变量的写操作对后续的读操作可见
传递性规则:A H-B B,B H-B C,那么A H-B C
管程中锁的规则:对一个锁的解锁 H-B于 后续对这个锁的加锁

保持原子性之互斥锁sychronized

锁对象:非静态this,静态Class,括号Object参数
预防死锁:
互斥:不能破坏
占有且等待:同时申请所有资源
不可抢占:sychronized解决不了,Lock可以解决
循环等待:给资源设置id字段,每次都是按顺序申请锁
等待通知机制:
wait、notify、notifyAll
可以使代码块保持原子性操作(保证代码块同时只能一个线程进行操作)
package com.xxx.cas;
 
public class PlusPlusOP {
	public static int var = 0;
	
	/*
	* 由于var++不是原子操作,所以需要synchronized同步代码块保持原子性
	*/
	public synchronized static void plusAndPlus(){
		var++;
	}
	
	public static void main(String[] args) {
		Thread threads[] = new Thread[20];
		for(int i=0;i<20;i++){
			threads[i] = new Thread(new Runnable() {
				
				@Override
				public void run() {
					for(int i=0;i<10000;i++){	
						plusAndPlus();
					}
				}
			});
			threads[i].start();
		}
		
		while(Thread.activeCount()>1){
			Thread.yield();
		}
		System.out.println("var=>"+var);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

会飞的小蜗

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

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

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

打赏作者

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

抵扣说明:

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

余额充值