实现一个显示锁

定义一个lock接口

package com.dwz.concurrency.chapter10;

import java.util.Collection;

public interface Lock {
    class TimeOutException extends Exception {
        public TimeOutException(String message) {
            super(message);
        }
    }

    void lock() throws InterruptedException;

    void lock(long mills) throws TimeOutException, InterruptedException;

    void unlock();

    Collection<Thread> getBlockedThread();

    int getBlockedSize();
}

lock的实现类

package com.dwz.concurrency.chapter10;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
/**
 *      实现一个显示锁lock
 */
public class BooleanLock2 implements Lock {
    //The initValue is true indicated the lock have be get.
    //The initValue is false indicated the lock is free(other thread can get this.)
    private boolean initValue;

    private Collection<Thread> blockedThreadCollection = new ArrayList<>();

    public BooleanLock2() {
        this.initValue = false;
    }

    @Override
    public synchronized void lock() throws InterruptedException {
        while (initValue) {
            blockedThreadCollection.add(Thread.currentThread());
            Optional.of(Thread.currentThread().getName() + " add the blockedThreadCollection....").ifPresent(System.out::println);
            this.wait();
        }

        blockedThreadCollection.remove(Thread.currentThread());
        this.initValue = true;
    }

    @Override
    public synchronized void unlock() {
        this.initValue = false;
        Optional.of(Thread.currentThread().getName() + " release the lock monitor....").ifPresent(System.out::println);
        this.notifyAll();
    }

    @Override
    public Collection<Thread> getBlockedThread() {
        return Collections.unmodifiableCollection(blockedThreadCollection);
    }

    @Override
    public int getBlockedSize() {
        return blockedThreadCollection.size();
    }

    @Override
    public void lock(long mills) throws TimeOutException, InterruptedException {
        return;
    }

}

此处wait()的是this对象,sychronized的也是this对象

测试类

package com.dwz.concurrency.chapter10;

import java.util.Optional;
import java.util.stream.Stream;
/**
 *  多线程的lock
 * @author dangwangzhen
 *
 */
public class LockTest {

    private static void work() throws InterruptedException {
        Optional.of(Thread.currentThread().getName() + " is working...").ifPresent(System.out::println);
        Thread.sleep(10_000);
    }
    public static void main(String[] args) throws InterruptedException {
        final BooleanLock2 booleanLock = new BooleanLock2();
        Stream.of("T1", "T2", "T3", "T4")
                .forEach(name ->
                    new Thread(() -> {
                        try {
                            booleanLock.lock();
                            Optional.of(Thread.currentThread().getName() + " have the lock Monitor...").ifPresent(System.out::println);
                            work();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } finally {
                            booleanLock.unlock();
                        }
                    }, name).start()
                );

        Thread.sleep(100);
        //缺点:该锁可能被其他线程释放(该锁被main线程释放)
        booleanLock.unlock();
    }
}

缺点:如果在线程执行过程中锁被main线程释放,不能保证 线程加的锁被线程自己释放

改进方法

package com.dwz.concurrency.chapter10;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
/**
 *      实现一个显示锁lock,并保证锁是由自己释放
 */
public class BooleanLock implements Lock {
    //The initValue is true indicated the lock have be get.
    //The initValue is false indicated the lock is free(other thread can get this.)
    private boolean initValue;

    //保证该锁只能被当前线程释放
    private Thread currentThread;

    private Collection<Thread> blockedThreadCollection = new ArrayList<>();

    public BooleanLock() {
        this.initValue = false;
    }

    @Override
    public synchronized void lock() throws InterruptedException {
        while (initValue) {
            blockedThreadCollection.add(Thread.currentThread());
            Optional.of(Thread.currentThread().getName() + " add the blockedThreadCollection....").ifPresent(System.out::println);
            this.wait();
        }

        blockedThreadCollection.remove(Thread.currentThread());
        this.initValue = true;
        this.currentThread = Thread.currentThread();
    }

    @Override
    public synchronized void unlock() {
        if(Thread.currentThread() == currentThread) {
            this.initValue = false;
            Optional.of(Thread.currentThread().getName() + " release the lock monitor....").ifPresent(System.out::println);
            this.notifyAll();
        }
    }

    @Override
    public Collection<Thread> getBlockedThread() {
        return Collections.unmodifiableCollection(blockedThreadCollection);
    }

    @Override
    public int getBlockedSize() {
        return blockedThreadCollection.size();
    }

}

原文地址:https://www.cnblogs.com/zheaven/p/12067950.html

时间: 2024-08-19 13:45:48

实现一个显示锁的相关文章

内部锁、显示锁和读写锁

线程同步机制 线程同步机制是一套用于协调线程间的数据访问及活动的机制.该机制用于保障线程安全及实现这些线程的共同目标. java平台提供的线程同步机制: 锁 volatile关键字 final关键字 static关键字 其他(如:Object.wait()/Object.notify()等) 锁机制 锁机制 :将多线程并发访问共享数据转换为串行访问,一个共享数据每次只能被一个线程访问(获得锁),该线程访问结束后(释放锁)其他线程才能对其访问. 锁的获得 : 一个线程在访问数据前必须申请相应的锁.

显示锁

之前在协调对共享对象的访问时可以使用的机制只有synchronized和volatile.java5.0增加了一种新的机制:ReentrantLock. Lock和ReentrantLock Lock提供了一种无条件的.可轮询的.定时的以及可中断的锁获取操作,所有加锁和解锁的方法都是显示的. ReentrantLock实现了Lock接口,并提供了与synchronized相同的互斥性和内存可见性.ReentrantLock可重入加锁. Lock接口的使用形式: Lock lock = new R

Java并发(基础知识)——显示锁和同步工具类

显示锁                                                                                     Lock接口是Java 5.0新增的接口,该接口的定义如下: public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long

多线程并发编程之显示锁ReentrantLock和读写锁

在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是可重入的锁,它不同于内置锁, 它在每次使用都需要显示的加锁和解锁, 而且提供了更高级的特性:公平锁, 定时锁, 有条件锁, 可轮询锁, 可中断锁. 可以有效避免死锁的活跃性问题.ReentrantLock实现了 Lock接口: public interface Lock { //阻塞直到获得锁或者中

oracle数据中记录被另一个用户锁住

原因:PL/SQL里面执行语句执行了很久都没有结果,于是中断执行,于是就直接在上面改字段,在点打钩(记入改变)的时候提示,记录被另一个用户锁住. 解决方法: 第一步:(只是用于查看哪些表被锁住,真正有用的是第二.第三步) select b.owner,b.object_name,l.session_id,l.locked_modefrom v$locked_object l, dba_objects bwhere b.object_id=l.object_id 显示如下: OWNER    OB

第十三章 显示锁

Java 5.0 提供的新的加锁机制:当内置加锁机制不适合时 , 作为一种可选择的高级功能 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 13.1 Lock 与 ReentrantLock Lock 中实现的必须提供与内置锁相同的内存可见 性语义, 但在加锁语义,调度算法,顺序保证和性能特性方面有所不同. 13.1.1 轮询锁和定时锁 在内置锁中, 解决死锁的唯一方法是 重新启动程序. 防止死锁的唯一

并发编程(四)显示锁

1.显示锁 Java程序可以依靠synchronized关键字隐式的获取锁实现锁功能,但是它将锁的获取和释放固话了,也就是先获取再释放. (synchronized是语言的特性(内置锁),Lock是一个类 使用的时候需要对其实例化 和方法调用,内存,CPU消耗较大.且JDK中对synchonized的优化已经做的很好,一般情况下没有特殊需求 尽量使用synchonized) 显示锁特性: 1)尝试非阻塞的获取锁:当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取,则成功获取并持有锁: 2)能被

Oracle 数据操作提示“记录被另一个用户锁住”

oracle数据中删除数据时提示“记录被另一个用户锁住” 解决方法: 1.查看数据库锁,诊断锁的来源及类型: select object_id,session_id,locked_mode from v$locked_object; 或者用以下命令: select b.owner,b.object_name,l.session_id,l.locked_mode from v$locked_object l, dba_objects b where b.object_id=l.object_id

一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁

前续 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(一)——地:起因 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁 平行时空 在复制好上面那一行我就先停下来了,算是先占了个位置,虽然我知道大概要怎么写,不过感觉还是很乱. 我突然想到,既然那么纠结,那么混乱,那么不知所措,我们不如换个视角.记得高中时看过的为数不多的长篇小说<穆斯林的葬礼>,作者是:霍达(女),故事描写了两个发生在不同时代.有着不同的内容却又交错扭结的爱情悲剧,一个是“玉”的故事,一个是“月”