在开发过程中 当我们拿到一个线程非安全的java类的时候,我们可以额外创建这个类的管理类 并在管理类中控制同步

比如

一个非线程安全的Pair类

package test.thread.sx.testKuai;

/**
* 线程非安全的java类
* 约束条件 两个变量的值必须一致
* @author Administrator
*
*/
public class Pair {
private int x,y;
public Pair(int x,int y){
this.x = x;
this.y = y;
}
public Pair(){
this(0,0);
}
public int getX() {
return x;
} public int getY() {
return y;
}
public void incrementX(){
x++;
}
public void incrementY(){
y++;
}
@Override
public String toString() {
return "Pair [x=" + x + ", y=" + y + "]";
}
public class PairValuesNotEqualException extends RuntimeException { private static final long serialVersionUID = 673137680063170443L; public PairValuesNotEqualException() {
super("Pair value not equal" + Pair.this);
}
}
public void checkState(){
if(x!=y){
throw new PairValuesNotEqualException();
}
} }

那么我们想要在线程安全的环境下来操作这个类的话 我们不可以修改原来类的代码结构 我们可以创建一个新的管理类 为了方便我们使用两种方式来实现同步

所以先创建一个abstract的类 然后在创建这个类的实现类

package test.thread.sx.testKuai;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; public abstract class PairManager {
protected Pair p = new Pair();
protected List<Pair> storge = Collections.synchronizedList(new ArrayList<Pair>()); /**
* 获取pair可以轻松管理同步
* @return
*/
public synchronized Pair getPair(){
return new Pair(p.getX(), p.getY());
}
public abstract void increment(); public void storge(Pair p){ storge.add(p); }
}

然后分别创建两个实现类  一个是直接同步方法 一个同步代码块

同步方法

package test.thread.sx.testKuai;

public class PairManager1 extends PairManager {
@Override
public synchronized void increment() {
p.incrementX();
p.incrementY();
storge(getPair());
} }

同步代码块

package test.thread.sx.testKuai;

public class PairManger2 extends PairManager {

    @Override
public void increment() {
Pair temp;
synchronized (this) {
p.incrementX();
p.incrementY();
temp = getPair();
}
storge(temp);
} }

其实还可以直接替换 LOCK

package test.thread.sx.testKuai;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class PairManger2 extends PairManager {
private Lock lock = new ReentrantLock(); @Override
public void increment() {
Pair temp;
/* synchronized (this) { */
lock.lock();
p.incrementX();
p.incrementY();
temp = getPair();
lock.unlock();
/* } */
storge(temp);
} }

在保证线程安全的情况下 为了性能最好是尽量减少同步范围

然后创建线程任务  这个是两个变量同时增加的任务

package test.thread.sx.testKuai;

public class PairManipulator implements Runnable {
private PairManager pm ;
public PairManipulator(PairManager pm) {
this.pm = pm;
}
@Override
public void run() {
while(true){
pm.increment();
System.out.println(pm.getPair());
} }
@Override
public String toString() {
return "pair:" + pm.getPair() ;
} }

然后创建一个检查任务

package test.thread.sx.testKuai;

public class PairChecker implements Runnable {
private PairManager pm; public PairChecker(PairManager p) {
pm = p;
} @Override
public void run() {
while (true) {
/* pm.checkCounter.incrementAndGet();*/
pm.getPair().checkState();
System.out.println(pm.getPair());
} } }

然后进行测试

package test.thread.sx.testKuai;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; public class CiiticalSection {
public static void testApproaches(PairManager pmn1,PairManager pmn2){
ExecutorService exc = Executors.newCachedThreadPool();
PairManipulator pm = new PairManipulator(pmn1);
PairManipulator pm2 = new PairManipulator(pmn2);
PairChecker pc = new PairChecker(pmn1);
PairChecker pc2 = new PairChecker(pmn2);
exc.execute(pm);
exc.execute(pm2);
exc.execute(pc);
exc.execute(pc2);

        exc.shutdown();
}
public static void main(String[] args) {
PairManager pmn1 = new PairManager1();
PairManager pmn2 = new PairManger2(); testApproaches(pmn1,pmn2); }
}

看下结果

-----------------
Pair [x=159948, y=159948]
Pair [x=159949, y=159949]
Pair [x=159950, y=159950]
--------------------

最新文章

  1. stm8s103串口
  2. python调用jar包类
  3. 拖动div简单事例代码
  4. XCode的安装包校验伪真
  5. android中ListView_SimpleAdapter
  6. Java基础-绘图技术
  7. PerformSelector may cause a leak because its selector is unknown 解决方法
  8. 使用 桌面的 chrome 远程调试 Android 的页面
  9. POJ1751--Highways(最小生成树,kauskal)
  10. 源码搭建lnmp平台
  11. Zigbee开发(1)
  12. Laravel 安装
  13. UISearchBar的扩展使用
  14. 201621123062《java程序设计》第九周作业总结
  15. sql server 复制表结构
  16. jQuery-day01-介绍 和 选择器获取元素
  17. JavaScript常用数组操作方法,包含ES6方法
  18. python-Requests + 正则表达式爬取猫眼电影
  19. Jmeter 批量执行脚本之-----------Ant
  20. netty01(长短连接、java)

热门文章

  1. HDU 4725 The Shortest Path in Nya Graph (最短路 )
  2. Housewife Wind
  3. Linux下测试CPU性能
  4. [洛谷P1501] [国家集训队]Tree II(LCT模板)
  5. 高性能JavaScript之加载和执行
  6. 【学习】SpringBoot之全局异常处理器
  7. 20175215 2018-2019-2 第四周Java课程学习总结
  8. oracle存储过程及sql优化-(三)
  9. es6 的数组的方法
  10. SpringMVC——-Controller返回格式化数据如JSON、XML的配置方式和机制