Java C 中的互斥體
雖然 Java 沒有 Mutex 類,但你可以使用 1 的訊號量來模仿 Mutex。以下示例執行帶有和不帶鎖定的兩個執行緒。如果沒有鎖定,程式會輸出一些輸出字元($或#)的隨機順序。通過鎖定,程式會發出漂亮,有序的#####或$$$$$字符集,但絕不會混合使用#&$。
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadLocalRandom;
public class MutexTest {
static Semaphore semaphore = new Semaphore(1);
static class MyThread extends Thread {
boolean lock;
char c = ' ';
MyThread(boolean lock, char c) {
this.lock = lock;
this.c = c;
}
public void run() {
try {
// Generate a random number between 0 & 50
// The random nbr is used to simulate the "unplanned"
// execution of the concurrent code
int randomNbr = ThreadLocalRandom.current().nextInt(0, 50 + 1);
for (int j=0; j<10; ++j) {
if(lock) semaphore.acquire();
try {
for (int i=0; i<5; ++i) {
System.out.print(c);
Thread.sleep(randomNbr);
}
} finally {
if(lock) semaphore.release();
}
System.out.print('|');
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
System.out.println("Without Locking:");
MyThread th1 = new MyThread(false, '$');
th1.start();
MyThread th2 = new MyThread(false, '#');
th2.start();
th1.join();
th2.join();
System.out.println('\n');
System.out.println("With Locking:");
MyThread th3 = new MyThread(true, '$');
th3.start();
MyThread th4 = new MyThread(true, '#');
th4.start();
th3.join();
th4.join();
System.out.println('\n');
}
}
執行 javac MutexTest.java; java MutexTest
,你會得到這樣的東西:
沒有鎖定:#$$$$$ | $$$$$ | $$#$$$ | $$$$$ | $$$$#$ | $$$$$ | $$$$$ | $# $$$$ | $$$$$ | $$$#$$ || ##### | ##### | ##### | ##### | ##### |# #### | ##### | ##### | ##### |
使用鎖定:$$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $ $$$$ | ##### | $$$$$ | ##### |
這是 C++中的相同示例:
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <random> // std::random_device
class MutextTest {
private:
static std::mutex mtx; // mutex for critical section
public:
static void run(bool lock, char c) {
// Generate a random number between 0 & 50
// The random nbr is used to simulate the "unplanned"
// execution of the concurrent code
std::uniform_int_distribution<int> dist(0, 50);
std::random_device rd;
int randomNbr = dist(rd);
//std::cout << randomNbr << '\n';
for(int j=0; j<10; ++j) {
if(lock) mtx.lock();
for (int i=0; i<5; ++i) {
std::cout << c << std::flush;
std::this_thread::sleep_for(std::chrono::milliseconds(randomNbr));
}
std::cout << '|';
if(lock) mtx.unlock();
}
}
};
std::mutex MutextTest::mtx;
int main()
{
std::cout << "Without Locking:\n";
std::thread th1 (MutextTest::run, false, '$');
std::thread th2 (MutextTest::run, false, '#');
th1.join();
th2.join();
std::cout << "\n\n";
std::cout << "With Locking:\n";
std::thread th3 (MutextTest::run, true, '$');
std::thread th4 (MutextTest::run, true, '#');
th3.join();
th4.join();
std::cout << '\n';
return 0;
}
執行 g++ --std=c++11 MutexTest.cpp; ./a.out
,你會得到這樣的東西:
沒有鎖定:$#$#$#$#$#| $ |#$#$#$#$#| $$ |#$#$#$#| $#$ |#$#$#$#| $ $#$ |#$#$#| $#$#$ |#$#$#| $#$$#$ |#$#| $#$#$#$ |#$#| $#$#$ #$$ |#| $#$#$#$#$ |#| #### |
使用鎖定:$$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $ $$$$ | ##### | $$$$$ | ##### |