操作系统课上讲过,信号机制最开始是用无限循环实现的,信号量只是一个int型整数。
wait(S) {
while(s<=0) {
; // no-op
}
S--;
}
signal(S) {
S++;
}
后来,将信号定义为结构体,由value和进程两部分组成。
typedef struct {
int value;
struct process * L;
} semaphore;
void wait(semaphore S) {
S.value--;
if(S.value < 0) {
add this process to S.L;
block();
}
}
void signal(semaphore S) {
S.value++;
if(S.value <= 0) {
remove a process from S.L;
wakeup(P);
}
}
很多学Java的同学,一直苦恼于多线程编程的问题。因为,Java JDK里的确提供了很多现成的线程操作方法,但是真正运用总是会抛出异常……。其实,Java提供的wait 和 notify 方法对于我们构建自己的并发控制模块已经是绰绰有余了。认识两个方法有两点必须要注意的:一,这两个方法是Object类的方法,也就是说Java中任何一个类都可以充当锁得角色;二,这两个方法必须放大synchronized 代码块里,以确保其执行时不受Java 多线程机制的影响。跟C写的信号量类比的话,wait 和 notify 相当于 block 和 wakeup ,而 synchronized 则确保wait 与 signal 方法的原子性。下面来看示例代码:
import java.util.LinkedList;
import core.concurrent.LockManager;
import core.concurrent.LockState;
public class LockerTest {
private static LockerTest locker = null;
public static LockerTest getLocker() {
if (locker == null) {
locker = new LockerTest();
}
return locker;
}
private volatile int count = 1;
private volatile LinkedList<Thread> waiting = new LinkedList<Thread>();
public synchronized void wait(String name) {
count--;
System.out.println(name + " wait " + count);
if (count < 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void signal() {
count++;
System.out.println("signal " + count);
if (count < 1) {
notify();
}
}
public static void main(String[] args) {
new Client("name1").start();
new Client("name2").start();
new Client("name3").start();
}
}
class Client extends Thread {
private String name;
public Client (String name) {
this.name = name;
}
public void run() {
LockManager.getLockManager().lock("adsf", LockState.excusive);
new ClientFood().show(name);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LockManager.getLockManager().unlock("adsf");
}
}
class ClientFood {
private static String name; // 这里的共享资源
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 这里需要并发控制的代码段
public void show(String newname) {
System.out.println("odd name = " + this.getName());
this.setName(newname);
for (int i = 0; i < 1000; i++) {
this.setName(newname + "_" + i);
}
System.out.println("new name = " + this.getName());
}
}
悠嘻,收工……
分享到:
相关推荐
Java进程信号量机制是多线程编程中一种有效的同步工具,它源于操作系统中的同步原语,用于管理和控制对共享资源的访问。在Java中,信号量由`java.util.concurrent.Semaphore`类实现,它提供了两种类型:可重用的二...
6. **实际编程中的应用**:在Java中,可以使用`java.util.concurrent.Semaphore`类来实现信号量。创建时指定初始值,然后在线程中调用`acquire()`(等价于P操作)和`release()`(等价于V操作)方法来管理资源访问。 ...
信号量机制是 Java 中的一种线程同步机制。信号量是一个整数值,表示当前可用的资源数量。线程可以通过等待信号量来获取资源访问权限。信号量机制可以用于解决生产者-消费者问题、哲学家就餐问题等。 Java 中的 ...
在哲学家就餐问题中,如果不使用信号量,我们也可以考虑使用synchronized来控制哲学家对筷子的访问,但这种方式可能不如信号量那样灵活。 总的来说,这个Java程序展示了如何使用多线程和同步技术解决并发问题,这...
通过使用信号量PV操作,实现了多线程同步,解决了理发师问题。下面是该解决方案的详细介绍。 信号量PV操作 信号量是一种同步机制,它可以用来解决多进程同步问题。PV操作是信号量的一种操作,它可以用来实现进程...
Redis作为一种高效、轻量级的内存数据存储,常被用作实现分布式锁的工具,而Java的信号量机制则是控制并发访问的一种策略。本篇文章将深入探讨Redis如何实现分布式锁以及Java中的信号量概念,并结合实际应用进行详细...
为了解决生产者-消费者问题,我们可以使用记录型信号量来实现生产者和消费者的同步。下面是一个简单的解决方案: 首先,我们定义三个信号量:mutex、empty 和 full。其中,mutex 是一个互斥信号量,用于保护缓冲池...
虽然Java标准库没有直接提供同步互斥结构,但它提供了基于对象锁的`wait()`和`notify()`方法,这使得我们可以实现Dijkstra的计数信号量概念。 信号量是一种在多线程编程中用于控制资源访问的机制。在Java中,可以...
在Java中,我们可以使用`java.util.concurrent.Semaphore`类来实现信号量。创建一个信号量时,可以指定初始许可证的数量。以下是一个简单的示例: ```java import java.util.concurrent.Semaphore; public class ...
在Python中,可以使用`threading.Semaphore`类来实现信号量。例如,创建一个计数信号量: ```python import threading semaphore = threading.Semaphore(3) # 创建一个值为3的信号量 def worker(): semaphore....
通过学习AQS,开发者不仅能够理解`ReentrantLock`和`CountDownLatch`的工作方式,还能进一步掌握如`ReentrantReadWriteLock`(读写锁)、`Semaphore`(信号量)等其他同步工具的实现原理。掌握AQS的使用,意味着具备了...
os课程设计、通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制
Java 信号量Semaphore的实现 Java 信号量Semaphore是Java并发编程中的一种机制,用于控制多个线程的并发执行。Semaphore的实现主要是通过计数器来实现的,每个Semaphore对象都维护着一个计数器,用于记录当前可用的...
本实验报告的目的是通过编写Java程序实现生产者消费者问题,掌握进程同步和互斥的方法,学习使用信号量机制解决进程互斥问题。 一、实验原理 生产者消费者问题是操作系统中最基本的同步问题。生产者进程生产产品,...
Java并发机制的底层实现原理涉及到多个方面,包括了本地内存与线程安全的问题、volatile关键字的使用、synchronized关键字的原理以及Java并发在处理器层面是如何实现的。通过这些机制,Java能够有效地管理多线程环境...
3. 使用共享变量和信号量实现线程间的通信。 4. 使用生产者-消费者模型来实现线程间的通信。 Java多线程通信机制的应用场景非常广泛,包括网络编程、数据库编程、图形用户界面编程等等。在这些场景中,多线程通信...
信号量机制正是为了解决这种问题而设计的。 信号量实质上是一个整型变量,可以被原子性地增加或减少。它有两个基本操作:P(wait)操作和V(signal)操作。P操作会尝试减少信号量的值,如果减少后信号量值小于0,...
**JAVA 多线程之信号量Semaphore实例详解** 在Java多线程编程中,信号量Semaphore是一种非常重要的同步工具,用于控制对公共资源的访问。Semaphore类位于`java.util.concurrent`包下,它允许我们限制同时访问特定...
Dijkstra提出的信号量机制的一部分。 首先,我们需要理解什么是进程同步和互斥。进程同步是指多个进程之间的协调,以确保它们按照特定的顺序或约定执行,避免数据不一致和竞争条件。互斥则是进程同步的一种特殊...
例如,创建一个线程池来并发加载图片,每个线程使用信号量来限制并发请求的数量,使用Looper处理回调到主线程的更新操作,同时利用缓存机制减少网络请求,优化用户体验。 总的来说,理解和熟练运用线程池、信号量、...