java实现自定义同步组件的过程
实现同步组件twinsLock:可以允许两个线程同时获取到锁,多出的其它线程将被阻塞。
以下是自定义的同步组件类,一般我们将自定义同步器Sync定义为同步组件TwinsLock的静态内部类。
实现同步器需要继承AbstractQueuedSynchronizer并覆盖相应的方法。
package com.lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class TwinsLock implements Lock {
private final Sync sync=new Sync(2);
//自定义一个同步器,作为自定义同步组件的静态内部类
private static final class Sync extends AbstractQueuedSynchronizer{
Sync(int count){
if(count<=0){
throw new IllegalArgumentException("count must large than zero");
}
setState(count);//设置同步状态
}
/**
* 尝试以共享方式获取同步状态
* return 大于0时表示获取成功
*/
@Override
public int tryAcquireShared(int reduceCount){
for(;;){
int current=getState();
int newCount=current-reduceCount;
if(newCount<0||compareAndSetState(current, newCount)){
return newCount;
}
}
}
/**
* 同步器中的释放同步状态的方法
*/
@Override
public boolean tryReleaseShared(int returnCount){
for(;;){
int current=getState();
int newCount=current+returnCount;
if(compareAndSetState(current, newCount)){
return true;
}
}
}
}
@Override
public void lock() {
sync.acquireShared(1);
}
@Override
public void unlock() {
sync.releaseShared(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
// TODO Auto-generated method stub
}
@Override
public Condition newCondition() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean tryLock() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean tryLock(long arg0, TimeUnit arg1)
throws InterruptedException {
// TODO Auto-generated method stub
return false;
}
}
下面是测试类,注意将线程实现类放在方法内和放在方法外时,对线程共享变量的区别
1,
package com.lock;
import java.util.concurrent.locks.Lock;
public class TwinsLockTest {
public static void main(String[] str) throws InterruptedException {
//将内部类放在方法内部,共享变量必须定义为final
final Lock twinsLock=new TwinsLock();
class Worker extends Thread{
public void run(){
while(true){
twinsLock.lock();
try{
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName());
Thread.sleep(10000);
}catch(Exception e){
e.printStackTrace();
}finally{
twinsLock.unlock();
}
}
}
}
for(int i=0;i<10;i++){
Worker worker=new Worker();
worker.setDaemon(true);
worker.start();
}
for(int i=0;i<10;i++){
Thread.sleep(500000);
System.out.println("....................");
}
}
}
2,
package com.lock;
import java.util.concurrent.locks.Lock;
public class TwinsLockTest2 {
//将外部类放在方法外面,共享变量必须定义为static才能保证同步。不然的话每个线程对象都拥有一个共享变量的拷贝
static Lock twinsLock=new TwinsLock();
public static void main(String[] str) throws InterruptedException {
for(int i=0;i<10;i++){
Worker worker=new TwinsLockTest2().new Worker();
worker.setDaemon(true);
worker.start();
}
for(int i=0;i<10;i++){
Thread.sleep(500000);
System.out.println("....................");
}
}
class Worker extends Thread{
public void run(){
while(true){
twinsLock.lock();
try{
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName());
Thread.sleep(2000);
}catch(Exception e){
e.printStackTrace();
}finally{
twinsLock.unlock();
}
}
}
}
}
java实现自定义同步组件的过程的更多相关文章
- 学习JUC源码(2)——自定义同步组件
前言 在之前的博文(学习JUC源码(1)--AQS同步队列(源码分析结合图文理解))中,已经介绍了AQS同步队列的相关原理与概念,这里为了再加深理解ReentranLock等源码,模仿构造同步组件的基 ...
- 011-多线程-基础-基于AbstractQueuedSynchronizer自定义同步组件
一.概述 队列同步器AbstractQueuedSynchronizer,是用来构建锁或者其他同步组件的基础框架. 1.1.自定义独占锁同步组件 设计一个同步工具:该工具在同一时刻,只允许一个线程访问 ...
- 基础篇:JAVA原子组件和同步组件
前言 在使用多线程并发编程的时,经常会遇到对共享变量修改操作.此时我们可以选择ConcurrentHashMap,ConcurrentLinkedQueue来进行安全地存储数据.但如果单单是涉及状态的 ...
- 构建锁与同步组件的基石AQS:深入AQS的实现原理与源码分析
Java并发包(JUC)中提供了很多并发工具,这其中,很多我们耳熟能详的并发工具,譬如ReentrangLock.Semaphore,它们的实现都用到了一个共同的基类--AbstractQueuedS ...
- AQS 原理以及 AQS 同步组件总结
1 AQS 简单介绍 AQS 的全称为(AbstractQueuedSynchronizer),这个类在 java.util.concurrent.locks 包下面. AQS 是一个用来构建锁和同步 ...
- Java显式锁学习总结之二:使用AbstractQueuedSynchronizer构建同步组件
Jdk1.5中包含了并发大神Doug Lea写的并发工具包java.util.concurrent,这个工具包中包含了显示锁和其他的实用同步组件.Doug Lea在构建锁和组件的时候,大多是以队列同步 ...
- Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析
1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...
- Java并发包源码学习系列:同步组件CountDownLatch源码解析
目录 CountDownLatch概述 使用案例与基本思路 类图与基本结构 void await() boolean await(long timeout, TimeUnit unit) void c ...
- java并发编程(7)构建自定义同步工具及条件队列
构建自定义同步工具 一.通过轮询与休眠的方式实现简单的有界缓存 public void put(V v) throws InterruptedException { while (true) { // ...
随机推荐
- YoloV3 训练崩溃
经过排查 发现是这里出了问题 然后发现是标注文件里有 x=0 y=0 这样的数据,46_Jockey_Jockey_46_576.txt , 那么肯定是标注文件出了问题!! 删除该标注文件即可. ...
- Git忽略已追踪文件或文件夹
今天拉取代码,用vs生成后发现obj文件夹下自动生成的文件被同事提交了,这个本应该加入到ignore的 我就需要把这个文件夹加入到gitignore, 不过已经追踪的文件和文件夹,直接添加到gitig ...
- SpringBoot实现定时器定时处理任务
最近在项目中遇到了一个问题, 对于新建的活动, 活动设置了开始时间和结束时间, 也就是数据库中的一个状态码的改变而已. 但是,这里就有问题了, 如何去实现到时间更改活动状态呢? 1. 刚开始的时候,我 ...
- 如何检测浏览器是否能用ActiveX
var xhr=false; function CreateXHR(){ try{ //检查能否用activexobject xhr=new ActiveXObject("msxml2.XM ...
- php压缩图片
<?php header('content-type:text/html;charset=utf8'); set_time_limit(0); $imgs=scandir('./Public/u ...
- rpc框架画 和spring cloud流程图
- android项目笔记整理(2)
31.利用SharedPreferences存储时间 读取时间: SharedPreferences sp=this.getSharedPreferences("actm&q ...
- js 扁平化输出数组
1.使用数组的flat方法 [1,2,[3,[4,5]]].flat(Infinity) //[1, 2, 3, 4, 5] 2.实现方式二: var arr = [[1, 2, 23], [13, ...
- easyUi的组合表格
公司之前的项目是用easyui写的里面还混搭着php...把分支下来,有点蒙.晚上回来恶补一下吧,今天渲染这个表格,我开始自己写假数据,然后用ajax操作再使用 obj.datagrid('loadD ...
- 【Struts2】Ognl与ValueStack
一.OGNL 1.1 概述 1.2 OGNL 五大类功能 1.3 演示 二.ValueStack 2.1 概述 2.2 ValueStack结构 2.3 结论 2.3 一些问题 三.OGNL表达式常见 ...