Semaphore,限制对共享资源访问的最大线程数量,要访问共享资源,需要先申请许可,申请到许可才能访问。访问结果了,释放许可。
线程的调用顺序如下:
Thread-1 申请一个许可,等待几秒钟,继续执行
Thread-2 申请2个许可,许可不足,阻塞
Thread-3 申请一个许可,等待几秒钟,继续执行
Thread-1,Thread-3,释放许可之后,Thread-2可以申请许可,成功执行。
import java.util.concurrent.Semaphore;
public class Task1 implements Runnable{
private Semaphore semaphore;
public Task1(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "获取到许可....");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + "执行....");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "释放许可....");
semaphore.release();
}
}
}
import java.util.concurrent.Semaphore;
public class Task2 implements Runnable{
private Semaphore semaphore;
public Task2(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "申请许可....");
semaphore.acquire(2);
System.out.println(Thread.currentThread().getName() + "获取到许可....");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + "执行....");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "释放许可....");
semaphore.release(2);
}
}
}
import java.text.ParseException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
public static void main(String[] args) throws ParseException, InterruptedException {
Semaphore semaphore = new Semaphore(2, true);
ReentrantLock lock = new ReentrantLock(true);
Condition condition = lock.newCondition();
Thread t1 = new Thread(new Task1(semaphore),"Thread-1");
t1.start();
Thread.sleep(2000);
Thread t2 = new Thread(new Task2(semaphore),"Thread-2");
Thread t3 = new Thread(new Task1(semaphore),"Thread-3");
t2.start();
t3.start();
}
}
此时,Thread-1申请一个,是足够的,返回成功,然后持有许可,此时state=1。
然后执行doReleaseShared,设置头节点状态为0,准备唤醒后继节点,也就是Thread-2.
此时,可能Thread-3还没有释放许可,state=1,那么Thread-2又会被阻塞。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。