• 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();
    }
    }
    }

    }

    }

  • 相关阅读:
    go语言第一问:在其他地方执行编译go语言程序,结果会在哪个地方产生?
    ip地址获取无效,自己修改ip地址
    linux和windows双向互通的压缩包格式zip
    在notepad++中tab和空格的区别
    Django ----- app 和 ORM的操作和介绍
    Mysql --- 索引
    Mysql --创建用户和授权,备份
    Mysql --数据的增删改
    Mysql -- 外键的变种 三种关系
    Mysql -- 完整性约束
  • 原文地址:https://www.cnblogs.com/yangwei20160911/p/6818883.html
Copyright © 2020-2023  润新知