多线程共享资源,比如一个对象的内存,怎样保证多个线程不会同时访问(读取或写入)这个对象,这就是并发最大的难题,因此产生了 互斥机制(锁)。
using the same monitor lock.
获取锁后,该线程本地存储失效,临界区(就是获得锁后释放锁之前 的代码区)从主存获取数据,并在释放锁后刷入主存。
互斥:
保证临界区代码线程间互斥。
synchronized实现同步的基础:
java中每个对象都可以作为锁
一个任务可以多次获得锁,比如在一个线程中调用一个对象的 synchronized标记的方法,在这个方法中调用第二个synchronized标记的方法,然后在第二个synchronized方法中调用第三个synchronized方法。一个线程每次进入一个synchronized方法中JVM都会跟踪加锁的次数,每次+1,当该这个方法执行完毕,JVM计数-1;当JVM计数为0时,锁完全被释放,其他线程可以访问该变量。
在使用并发时将对象的field设为private 很重要!尤其是使用static变量(evil static variable) 使用 Lock lock =new ReentrantLock()的问题是代码不够优雅,增加代码量;我们一般都是使用synchronized实现互斥机制。但是1.当代码中抛出异常时,显示锁的finally里可以进行资源清理工作。2.ReentrantLock还给我们更细粒度的控制力
2. 有哪些Java web里的并发框架,都有哪些
一、并发是一种需求,以下先介绍一下javaweb对于高并发的处理思路:
1、synchronized 关键字
可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。可能锁对象包括: this, 临界资源对象,Class 类对象
2、同步方法
同步方法锁定的是当前对象。当多线程通过同一个对象引用多次调用当前同步方法时, 需同步执行。
3、同步代码块
同步代码块的同步粒度更加细致,是商业开发中推荐的编程方式。可以定位到具体的同步位置,而不是简单的将方法整体实现同步逻辑。在效率上,相对更高。
A)锁定临界对象
同步代码块在执行时,是锁定 object 对象。当多个线程调用同一个方法时,锁定对象不变的情况下,需同步执行。
B)锁定当前对象
4、锁的底层实现
Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现。同步方法 并不是由 monitor enter 和 monitor exit 指令来实现同步的,而是由方法调用指令读取运行时常量池中方法的 ACC_SYNCHRONIZED 标志来隐式实现的。
5、锁的种类
Java 中锁的种类大致分为偏向锁,自旋锁,轻量级锁,重量级锁。
锁的使用方式为:先提供偏向锁,如果不满足的时候,升级为轻量级锁,再不满足,升级为重量级锁。自旋锁是一个过渡的锁状态,不是一种实际的锁类型。
锁只能升级,不能降级。
6、volatile 关键字
变量的线程可见性。在 CPU 计算过程中,会将计算过程需要的数据加载到 CPU 计算缓存中,当 CPU 计算中断时,有可能刷新缓存,重新读取内存中的数据。在线程运行的过程中,如果某变量被其他线程修改,可能造成数据不一致的情况,从而导致结果错误。而 volatile 修饰的变量是线程可见的,当 JVM 解释 volatile 修饰的变量时,会通知 CPU,在计算过程中, 每次使用变量参与计算时,都会检查内存中的数据是否发生变化,而不是一直使用 CPU 缓存中的数据,可以保证计算结果的正确。
更多、此外还有很多细节需要通过学习去了解和完善,此处就不一一列举了。
二、并发框架
并发框架很多,如ExecutorService、RxJava、Disruptor、Akka等,具体选择哪个(或者都不选择)是根据项目需求选择的,框架本身的差异并不大,基本都是如下模式
3. java中什么是并发,如何解决
多个进程或线程同时(或着说在同一段时间内)访问同一资源会产生并发问题。 银行两操作员同时操作同一账户就是典型的例子。比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户减去
50元,A先提交,B后提交。 最后实际账户余额为1000-50=950元,但本该为 1000+100-50=1050。这就是典型的并发问题。
可以用锁解决。
关于锁我也不是太清楚,你可以研究一下.....
4. Java如何处理大量的并发请求
在web应用中,同一时间有大量的客户端请求同时发送到服务器,例如抢购、秒杀等。这个时候如何避免将大量的请求同时发送到业务系统。
第一种方法:在容器中配置最大请求数,如果大于改请求数,则客户端阻塞。该方法有效的阻止了大量的请求同时访问业务系统,但对用于不友好。
第二种方法:使用过滤器,保证一定数量的请求能够正常访问系统,多余的请求先跳转到排队页面,由排队页面定时发起请求。过滤器实现如下:
<pre name="code" class="java">public class ServiceFilter implements Filter { private static final int MAX_COUNT = 20; private int filterCount = 0; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("before"+filterCount); if(filterCount > MAX_COUNT) { //请求个数太多,跳转到排队页面 request.getRequestDispatcher("index.jsp").forward(request, response); } else { //请求个数加1 filterCount ++; chain.doFilter(request, response); //访问结束,请求个数减1 filterCount --; } }
}
5. 濡备綍澶勭悊java楂桦苟鍙戦梾棰
濡备綍澶勭悊骞跺彂鍜屽悓姝
浠婂ぉ璁茬殑濡备綍澶勭悊骞跺彂鍜屽悓钖屾ラ梾棰树富瑕佹槸阃氲繃阌佹満鍒躲
鎴戜滑闇瑕佹槑锏斤纴阌佹満鍒舵湁涓や釜灞傞溃銆
涓绉嶆槸浠g爜灞傛′笂镄勶纴濡俲ava涓镄勫悓姝ラ挛锛屽吀鍨嬬殑灏辨槸钖屾ュ叧阌瀛梥ynchronized锛岃繖閲屾垜涓嶅湪锅氲繃澶氱殑璁茶В锛
镒熷叴瓒g殑鍙浠ュ弬钥:http://www.cnblogs.com/xiohao/p/4151408.html
鍙﹀栦竴绉嶆槸鏁版嵁搴揿眰娆′笂镄勶纴姣旇缉鍏稿瀷镄勫氨鏄鎭茶傞挛鍜屼箰瑙傞挛銆傝繖閲屾垜浠閲岖偣璁茶В镄勫氨鏄鎭茶傞挛锛堜紶缁熺殑鐗╃悊阌侊级鍜屼箰瑙傞挛銆
鎭茶傞挛(Pessimistic Locking):
鎭茶傞挛锛屾e傚叾钖嶏纴瀹冩寚镄勬槸瀵规暟鎹琚澶栫晫锛埚寘𨰾链绯荤粺褰揿墠镄勫叾浠栦簨锷★纴浠ュ强𨱒ヨ嚜 澶栭儴绯荤粺镄勪簨锷″勭悊锛変慨鏀规寔淇濆畧镐佸害锛屽洜姝わ纴
鍦ㄦ暣涓鏁版嵁澶勭悊杩囩▼涓锛屽皢鏁版嵁澶勪簬阌佸畾鐘舵併
鎭茶傞挛镄勫疄鐜帮纴寰寰渚濋潬鏁版嵁搴撴彁渚涚殑阌佹満鍒讹纸涔熷彧链夋暟鎹搴揿眰鎻愪緵镄勯挛链哄埗镓嶈兘 鐪熸d缭璇佹暟鎹璁块梾镄勬帓浠栨э纴钖﹀垯锛屽嵆浣垮湪链绯荤粺
涓瀹炵幇浜嗗姞阌佹満鍒讹纴涔熸棤娉曚缭璇佸栭儴绯 缁熶笉浼氢慨鏀规暟鎹锛夈
涓涓鍏稿瀷镄勫氲禆鏁版嵁搴撶殑鎭茶傞挛璋幂敤锛
select * from account where name=钬滶rica钬 for update
杩欐浔 sql 璇鍙ラ挛瀹氢简 account 琛ㄤ腑镓链夌﹀悎妫绱㈡浔浠讹纸 name=钬滶rica钬 锛夌殑璁板綍銆
链娆′簨锷℃彁浜や箣鍓嶏纸浜嫔姟鎻愪氦镞朵细閲婃斁浜嫔姟杩囩▼涓镄勯挛锛夛纴澶栫晫镞犳硶淇鏀硅繖浜涜板綍銆
Hibernate 镄勬偛瑙傞挛锛屼篃鏄锘轰簬鏁版嵁搴撶殑阌佹満鍒跺疄鐜般
涓嬮溃镄勪唬镰佸疄鐜颁简瀵规煡璇㈣板綍镄勫姞阌侊细
String hqlStr ="from TUser as user where user.name='Erica'";
Query query = session.createQuery(hqlStr);
query.setLockMode("user",LockMode.UPGRADE); // 锷犻挛
List userList = query.list();// 镓ц屾煡璇锛岃幏鍙栨暟鎹
query.setLockMode 瀵规煡璇㈣鍙ヤ腑锛岀壒瀹氩埆钖嶆墍瀵瑰簲镄勮板綍杩涜屽姞阌侊纸鎴戜滑涓 TUser 绫绘寚瀹氢简涓涓鍒钖 钬涡ser钬 锛夛纴杩欓噷涔熷氨鏄瀵
杩斿洖镄勬墍链 user 璁板綍杩涜屽姞阌併
瑙傚疗杩愯屾湡 Hibernate 鐢熸垚镄 SQL 璇鍙ワ细
select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id
as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex
from t_user tuser0_ where (tuser0_.name='Erica' ) for update
杩欓噷 Hibernate 阃氲繃浣跨敤鏁版嵁搴撶殑 for update 瀛愬彞瀹炵幇浜嗘偛瑙傞挛链哄埗銆
Hibernate 镄勫姞阌佹ā寮忔湁锛
Ø LockMode.NONE 锛 镞犻挛链哄埗銆
Ø LockMode.WRITE 锛 Hibernate 鍦 Insert 鍜 Update 璁板綍镄勬椂鍊欎细镊锷ㄨ幏鍙
Ø LockMode.READ 锛 Hibernate 鍦ㄨ诲彇璁板綍镄勬椂鍊欎细镊锷ㄨ幏鍙栥
浠ヤ笂杩欎笁绉嶉挛链哄埗涓鑸鐢 Hibernate 鍐呴儴浣跨敤锛屽 Hibernate 涓轰简淇濊瘉 Update
杩囩▼涓瀵硅薄涓崭细琚澶栫晫淇鏀癸纴浼氩湪 save 鏂规硶瀹炵幇涓镊锷ㄤ负鐩镙囧硅薄锷犱笂 WRITE 阌併
Ø LockMode.UPGRADE 锛氩埄鐢ㄦ暟鎹搴撶殑 for update 瀛愬彞锷犻挛銆
Ø LockMode. UPGRADE_NOWAIT 锛 Oracle 镄勭壒瀹氩疄鐜帮纴鍒╃敤 Oracle 镄 for
update nowait 瀛愬彞瀹炵幇锷犻挛銆
涓婇溃杩欎袱绉嶉挛链哄埗鏄鎴戜滑鍦ㄥ簲鐢ㄥ眰杈冧负甯哥敤镄勶纴锷犻挛涓鑸阃氲繃浠ヤ笅鏂规硶瀹炵幇锛
Criteria.setLockMode
Query.setLockMode
Session.lock