博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA并发处理经验(三)锁的优化与注意
阅读量:5928 次
发布时间:2019-06-19

本文共 5249 字,大约阅读时间需要 17 分钟。

一、前言

二、锁的建议

1、锁的分化,具体可以借鉴block queue的take与put分锁

2、锁定定义块合适,不适合太大也不适合太小

3、JAVA虚拟机自带锁一步步:

3.1 锁偏向(统一进程直接进入同步)------》

3.2 轻量级锁(开启:-XX:+UseBiasedLockong)------》

3.3 自旋锁(空循环,等待)-----》

3.4锁消除(是否真需要同步分析,开启逃逸分析:-XX:+EliminateLocks)

4、ThreadLocal工具,原理:开很多线程来做同一份工作。缺点:线程不安全,不能操作共享数据

应用场景:

* 应用场景:*1、存放当前session用户:quake want的jert2、存放一些context变量,比如webwork的ActionContext3、存放session,比如Spring hibernate orm的session
package lock;import jDKMulit.CountDownLathDemo;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.CountDownLatch;import java.util.concurrent.Executor;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * Created by ycy on 16/1/14. */public class ThreadLocalDemo_Gc {    static volatile ThreadLocal
t1=new ThreadLocal
(){ @Override protected void finalize() throws Throwable{ System.out.println(this.toString()+" is gc"); } }; static volatile CountDownLatch cd=new CountDownLatch(1000);//线程计算器 ,叨叨1000次调用之后不在等待 public static class ParseDare implements Runnable{ int i=0; public ParseDare(int i){ this.i=i; } public void run() { try { if (t1.get()==null){ t1.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"){ @Override protected void finalize() throws Throwable { System.out.println(this.toString()+" is gc"); } }); System.out.println(Thread.currentThread().getId()+"create SimpleDatefromat"); } Date t=t1.get().parse("2015-03-29 19:29:"+i%60); } catch (ParseException e) { e.printStackTrace(); }finally { cd.countDown(); } } } public static void main(String[] args) throws InterruptedException { ExecutorService es= Executors.newFixedThreadPool(10); for (int i = 0; i <1000 ; i++) { es.execute(new ParseDare(i)); } cd.await(); System.out.println("misson complete"); t1=null; System.gc(); System.out.println("frist FC complete"); //在设置ThreadLocal的时候,会清楚ThreadMap中无效的对象 t1=new ThreadLocal
(); cd=new CountDownLatch(1000); for (int i = 0; i <1000 ; i++) { es.execute(new ParseDare(i)); } cd.await(); Thread.sleep(1000); System.gc(); System.out.println(" second GC complete"); }}

5、牛叉:忘掉我们该死得锁是哟高CAS操作,这么做直接跟CPU交道适用Atomic Integer  long reference 等等,都可以适用。

package lock;import java.util.concurrent.atomic.AtomicStampedReference;/** * Created by ycy on 16/1/14. * cas:比较交换 * 用AtomicStampedReference 封装对象; * 景:对数据库进行查询更换,例如消费充值等等 */public class AtomicStampedRefrenceDemo {    static AtomicStampedReference
money=new AtomicStampedReference
(19,0);//引用对象,初始时间戳 public static void main(String[] args) { //模拟多个线程更新数据库,为用户充值 for (int i = 0; i <3 ; i++) { final int timestamp= money.getStamp();//获取时间戳 new Thread(){ @Override public void run() { while (true){ while (true){ Integer m=money.getReference(); if(m<20){ if (money.compareAndSet(m,m+20,timestamp,timestamp+2)){ System.out.println("余额小于20元,充值成功,余额为"+money.getReference()+"元"); break; } }else{ System.out.println("余额大于20,无须充值"); break; } } } } }.start(); } //用户消费线程 模拟 new Thread(){ @Override public void run() { for (int i = 0; i <3 ; i++) { while(true){ int timestamp=money.getStamp(); Integer m=money.getReference(); if (m>10){ System.out.println("大于10元"); if (money.compareAndSet(m,m-10,timestamp,timestamp+1)){ System.out.println("成功消费10元,余额为"+money.getReference()); break; } }else{ System.out.println("没有足够资金"); break; } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); }}

6、死锁产生的要素“

6.1、互斥使用(资源独占) 
一个资源每次只能给一个进程使用 
6.2、不可强占(不可剥夺) 
资源申请者不能强行的从资源占有者手中夺取资源,资源只能由占有者自愿释放 
6.3、请求和保持(部分分配,占有申请) 
一个进程在申请新的资源的同时保持对原有资源的占有(只有这样才是动态申请,动态分配) 
6.4、循环等待 
存在一个进程等待队列 
{P1 , P2 , … , Pn}, 
其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路

转载地址:http://ikrvx.baihongyu.com/

你可能感兴趣的文章
俺的新书《Sencha Touch实战》终于出版了
查看>>
【mybatis】mybatis 查询mysql 长编码的查询使用 正向查询和反向查询,避免数据库关系 递归查询的 解决方案...
查看>>
使用GDAL下载并转换SRTM的DEM数据(二)
查看>>
Yii2 引入 css js
查看>>
Android系统Google Maps开发实例浅析
查看>>
实例 | 能源区块链、物联网技术在智能电网中的趋势及前沿应用
查看>>
Valgrind 例子
查看>>
SignalR
查看>>
password
查看>>
CSS浮动专题!
查看>>
adb的使用
查看>>
深浅拷贝
查看>>
细说PHP中strlen和mb_strlen的区别
查看>>
AJAX介绍
查看>>
JavaWeb的历史与发展趋势
查看>>
线性方程组迭代求解——Gauss-Seidel迭代算法(Python实现)
查看>>
WEB程序设计 第7版
查看>>
壳的执行过程
查看>>
ACdream 1093 女神的正多面体 矩阵快速幂
查看>>
好文章集锦目录
查看>>