gpt4 book ai didi

自定义线程锁

转载 作者:知者 更新时间:2024-03-13 04:27:06 25 4
gpt4 key购买 nike

一 点睛

构造一个线程锁 BooleanLock,使其具备 synchronized 关键字所有功能的同时又具备可中断和 lock 超时功能。

二 实战

1 接口

package concurrent.booleanLock;

import java.util.List;
import java.util.concurrent.TimeoutException;

public interface Lock {
    // 该方法用于阻塞,除非获得到了锁,这一点和 synchronized 非常类似,但是该方法是可中断的,中断时抛出 InterruptedException
    void lock() throws InterruptedException;

    // 该方法除了可以被中断以外,还增加了对应的超时功能
    void lock(long mills) throws InterruptedException, TimeoutException;

    // 进行锁的释放
    void unLock();

    // 用于获取当前有哪些线程被阻塞
    List<Thread> getBlockedThreads();
}

2 接口实现代码

package concurrent.booleanLock;

import java.util.*;
import java.util.concurrent.TimeoutException;

public class BooleanLock implements Lock {
    private Thread currentThread;

    private boolean locked = false;

    private final List<Thread> blockedList = new ArrayList<>();

    @Override
    public void lock() throws InterruptedException {
        synchronized (this) {
            while (locked) {
                final Thread tempThread = Thread.currentThread();
                try {
                    if (!blockedList.contains(tempThread)) {
                        blockedList.add(Thread.currentThread());
                    }
                    this.wait();
                } catch (InterruptedException e) {
                    blockedList.remove(tempThread);
                    throw e;
                }
            }
            blockedList.remove(Thread.currentThread());
            this.locked = true;
            this.currentThread = Thread.currentThread();
        }
    }

    @Override
    public void lock(long mills) throws InterruptedException, TimeoutException {
        synchronized (this) {
            if (mills <= 0) {
                this.lock();
            } else {
                long remainingMills = mills;
                long endMills = System.currentTimeMillis() + remainingMills;
                while (locked) {
                    if (remainingMills <= 0) {
                        throw new TimeoutException("can not get the lock during " + mills + " ms");
                    }
                    if (!blockedList.contains(Thread.currentThread())) {
                        blockedList.add(Thread.currentThread());
                    }
                    this.wait(remainingMills);
                    remainingMills = endMills - System.currentTimeMillis();
                }
                blockedList.remove(Thread.currentThread());
                this.locked = true;
                this.currentThread = Thread.currentThread();
            }
        }
    }

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

    @Override
    public List<Thread> getBlockedThreads() {
        return Collections.unmodifiableList(blockedList);
    }
}

3 测试代码

package concurrent.booleanLock;

import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class BooleanLockTest {
    private final Lock lock = new BooleanLock();

    public void syncMethod() {
        try {
            lock.lock();
            int randomInt = new Random().nextInt(10);
            System.out.println(Thread.currentThread() + " get the Lock.");
            TimeUnit.SECONDS.sleep(randomInt);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unLock();
        }
    }

    public void syncMethodTimeout() {
        try {
            lock.lock(1000);
            int randomInt = new Random().nextInt(10);
            System.out.println(Thread.currentThread() + " get the Lock.");
            TimeUnit.SECONDS.sleep(randomInt);
        } catch (InterruptedException | TimeoutException e) {
            e.printStackTrace();
        } finally {
            lock.unLock();
        }
    }

    public static void main(String[] args) {
        // 1 多个线程通过 lock() 方法争抢锁
//        BooleanLockTest test = new BooleanLockTest();
//        IntStream.range(0, 10).mapToObj(i -> new Thread(test::syncMethod)).forEach(Thread::start);
        // 2 可中断被阻塞的线程
//        BooleanLockTest test1 = new BooleanLockTest();
//        new Thread(test1::syncMethod, "T1").start();
//        try {
//            TimeUnit.MILLISECONDS.sleep(2);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        Thread t2 = new Thread(test1::syncMethod, "T2");
//        t2.start();
//        try {
//            TimeUnit.MILLISECONDS.sleep(10);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        t2.interrupt();
        // 3 阻塞的线程可超时
        BooleanLockTest test2 = new BooleanLockTest();
        new Thread(test2::syncMethod, "T1").start();
        try {
            TimeUnit.MILLISECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Thread t2 = new Thread(test2::syncMethodTimeout, "T2");
        t2.start();
        try {
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

三 测试结果

1 多个线程通过 lock() 方法争抢锁

Thread[Thread-0,5,main] get the Lock.

Thread-0 release ths lock.

Thread[Thread-7,5,main] get the Lock.

Thread-7 release ths lock.

Thread[Thread-1,5,main] get the Lock.

Thread-1 release ths lock.

Thread[Thread-6,5,main] get the Lock.

Thread-6 release ths lock.

Thread[Thread-2,5,main] get the Lock.

Thread-2 release ths lock.

Thread[Thread-9,5,main] get the Lock.

Thread-9 release ths lock.

Thread[Thread-4,5,main] get the Lock.

Thread-4 release ths lock.

Thread[Thread-8,5,main] get the Lock.

Thread-8 release ths lock.

Thread[Thread-5,5,main] get the Lock.

Thread-5 release ths lock.

Thread[Thread-3,5,main] get the Lock.

Thread-3 release ths lock.

2 可中断被阻塞的线程

Thread[T1,5,main] get the Lock.

java.lang.InterruptedException

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:502)

at concurrent.booleanLock.BooleanLock.lock(BooleanLock.java:22)

at concurrent.booleanLock.BooleanLockTest.syncMethod(BooleanLockTest.java:12)

at java.lang.Thread.run(Thread.java:748)

3 阻塞的线程可超时

Thread[T1,5,main] get the Lock.

java.util.concurrent.TimeoutException: can not get the lock during 1000 ms

at concurrent.booleanLock.BooleanLock.lock(BooleanLock.java:44)

at concurrent.booleanLock.BooleanLockTest.syncMethodTimeout(BooleanLockTest.java:25)

at java.lang.Thread.run(Thread.java:748)

T1 release ths lock.

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com