Java introduced Semaphore since 1.5, let's see how we can use it to maintain an order for thread access.
Suppose we have the following code:
class Foo {
public:
A(.....);
B(.....);
}
Foo f;
f.A(.....);
f.B(.....);
f.C(.....);
Suppose we have the following code to use class Foo. We do not know how the threads
will be scheduled in the OS.
Foo f;
f.A(.....);
f.B(.....);
f.C(.....);
f.A(.....);
f.B(.....);
f.C(.....);
i) Can you design a mechanism to make sure that all the methods will be executed in
sequence?
--------------------------------------
we can use Semaphore sem = new Semaphore(1) to init a mutex, at this time, available permit for this semaphore is 1.
we can use sem.acquire() for P operation, so the permit will be reduced to 0, any other places uses sem.acquire() will be blocked until sem.release() is called and permit is increased to 1 again. So to maintain an access order, we wanna acquire semaphore first and use predecessor to release this semaphore.
public class SemaphoreTest {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
final Semaphore sem_c = new Semaphore(1);
final Semaphore sem_b = new Semaphore(1); //permit is 1
final Semaphore sem_all = new Semaphore(1);
System.out.println("first, sem_b permit: " + sem_b.availablePermits());
System.out.flush();
sem_b.acquire(); //permit from 1 to 0
System.out.println("after acquire, sem_b permit: " + sem_b.availablePermits());
System.out.flush();
sem_c.acquire();
sem_all.acquire();
A(sem_b);
B(sem_c, sem_b);
C(sem_c, sem_all, sem_b);
// System.out.println("second round");
System.out.flush();
System.out.println("sem_all permit: " + sem_all.availablePermits());
sem_all.acquire();
System.out.println("sem_b permit: " + sem_b.availablePermits());
sem_b.acquire();
sem_c.acquire();
//
A(sem_b);
B(sem_c, sem_b);
C(sem_c, sem_all, sem_b);
}
private static void C(final Semaphore sem_c, final Semaphore sem_all, final Semaphore sem_b) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
sem_c.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("c");
System.out.flush();
sem_c.release();
// System.out.println("sem_all permit: " + sem_all.availablePermits());
sem_all.release();
}}).start();
}
private static void B(final Semaphore sem_c, final Semaphore sem_b) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(1000);
sem_b.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sem_b.release();
System.out.println("b");
System.out.flush();
sem_c.release();
}}).start();
}
private static void A(final Semaphore sem_b) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("a");
System.out.flush();
// System.out.println("sem_b permit: " + sem_b.availablePermits());
sem_b.release();
// System.out.println("sem_b permit after: " + sem_b.availablePermits());
System.out.flush();
}}).start();
}
}
分享到:
相关推荐
《深入浅出Java Semaphore》 Semaphore,中文通常称为信号量,是Java并发编程中的一种重要工具,自JDK 1.5版本起被引入。它主要用于控制对特定资源的并发访问,确保资源得到合理的使用。Semaphore维护了一组虚拟的...
Java中的Semaphore是一个并发控制工具,属于java.util.concurrent包下的一个类,它的主要作用是限制对共享资源的访问权限,以实现多线程环境中的同步和限流。Semaphore类提供了信号量的概念,允许我们设定一个固定的...
Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有...
java buffer using Semaphore a kind of example of writer and reader
Semaphore是Java并发编程中的一种重要工具,主要用于控制并发线程的访问权限,实现限流或资源的互斥访问。在高并发场景下,Semaphore能够有效地防止过多的线程同时访问共享资源,从而避免系统资源耗尽,提高系统性能...
Semaphore(信号量)是一种经典的同步机制,它源自于荷兰计算机科学家Edsger W. Dijkstra提出的银行家算法。本示例中,我们将深入探讨如何使用Semaphore来控制多线程的循序执行。 Semaphore是一种计数信号量,它...
本文将深入探讨如何利用Java实现限流,并关注于使用Semaphore作为令牌桶和漏桶算法的实现,以及在数据线程数量限制上的应用。 首先,我们需要了解限流的基本概念。限流的主要目标是确保系统在高负载下仍能保持稳定...
在Java中,`java.util.concurrent.Semaphore`类为我们提供了信号量的功能,它允许我们限制同时访问某个资源的线程数量,从而实现线程同步和资源管理。 信号量主要包含两种类型:可重用信号量(非递减信号量)和二...
Java 5.0引入了四个新的同步工具类,它们是Semaphore、CountDownLatch、CyclicBarrier和Exchanger,用于解决线程间的同步问题。本篇将重点讲解Semaphore类。 Semaphore,顾名思义,就像是一个信号灯或通行证,用来...
Java同步是Java编程中一个非常重要的概念,主要涉及到多线程环境下的程序控制。在Java中,当多个线程同时访问共享资源时,如果没有适当的同步机制,可能会导致数据不一致、竞态条件等问题。同步机制确保了在特定时间...
本文将详细解析Java并发工具类,并通过示例代码介绍`CountDownLatch`、`CyclicBarrier`、`Phaser`、`Semaphore`和`ThreadLocal`的用法。 1. **CountDownLatch** `CountDownLatch`是一个计数器,通常用于等待多个...
### JAVA并发编程与高并发解决方案 #### 一、并发编程基础 ##### 1.1 并发的概念 在计算机科学中,并发是指多个任务或进程同时进行的现象。它不同于并行,后者指的是多个处理器或核心同时执行不同的指令。在Java中...
除了`synchronized`,Java提供了丰富的并发工具类,如`Semaphore`(信号量)或`ReentrantLock`(可重入锁),它们可以更灵活地控制并发。例如,可以使用`Semaphore`来模拟筷子的可用性,限制同时可以被拿取的筷子...
Semaphore是Java并发编程中的一种重要工具,用于控制对有限资源的访问权限,它可以理解为一种计数信号量。与独占锁ReentrantLock不同,Semaphore允许多个线程同时访问同一资源,但会限制同时访问的数量。在Java中,...
- **`java.util.concurrent`包**:提供了大量并发工具类和接口,如`ExecutorService`、`Future`、`Semaphore`等。 - **`java.lang.Thread`类**:用于创建线程的基础类。 - **`Runnable`接口**:定义了线程体的执行...
在Java并发编程中,CountDownLatch、CyclicBarrier和Semaphore是三种重要的线程协作工具,它们都基于AbstractQueuedSynchronizer(AQS)框架来实现线程间的同步和协调。AQS是一个内置的锁和同步组件,它为构建高级...
### Java多线程编程总结 #### 一、Java多线程基础 在Java中,多线程编程是一项非常重要的技术,它能够有效地提高程序的执行效率,并行处理多个任务。多线程编程的核心在于理解线程的创建方式、生命周期以及线程间...
**JAVA 多线程之信号量Semaphore实例详解** 在Java多线程编程中,信号量Semaphore是一种非常重要的同步工具,用于控制对公共资源的访问。Semaphore类位于`java.util.concurrent`包下,它允许我们限制同时访问特定...
java.Semaphore(处理方案示例).md
在Java的并发编程中,Semaphore 是一个非常重要的同步辅助类,它用于控制对共享资源的访问。Semaphore 通过维护一个许可集来控制同时访问特定资源的线程数量,从而避免资源竞争和潜在的性能问题。本文将详细介绍 ...