package com.strind.jucdemo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* @author strind
* @date 2024/10/20 10:38
* @description 作業
*/
public class ThirdLock implements Lock {
private final Sync sync = new Sync(3);
public static final class Sync extends AbstractQueuedSynchronizer{
Sync(int count){
if (count < 0){
throw new IllegalArgumentException("同步狀態不得小於0");
}
setState(count);
}
@Override
protected int tryAcquireShared(int arg) {
while (true){
int cur = getState();
int lost = cur - arg;
if (lost < 0 || compareAndSetState(cur,lost)){
return lost;
}
}
}
@Override
protected boolean tryReleaseShared(int arg) {
while (true){
int cur = getState();
int have = cur + arg;
if (compareAndSetState(cur,have)){
return true;
}
}
}
}
@Override
public void lock(){
sync.acquireShared(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public void unlock() {
sync.releaseShared(1);
}
@Override
public Condition newCondition() {
return null;
}
}
package com.strind.jucdemo;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
/**
* @author strind
* @date 2024/10/20 10:43
* @description 測試類
*/
public class ThirdLockTest {
public static void main(String[] args) throws InterruptedException {
Lock lock = new ThirdLock();
CountDownLatch latch = new CountDownLatch(10);
class Worker extends Thread {
@Override
public void run() {
while (true){
lock.lock();
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("threadName ==> " + Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(1);
latch.countDown();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}
}
for (int i = 0; i < 10; i++) {
Worker worker = new Worker();
worker.start();
}
latch.await();
}
}