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
,你会得到这样的东西:
没有锁定:$#$#$#$#$#| $ |#$#$#$#$#| $$ |#$#$#$#| $#$ |#$#$#$#| $ $#$ |#$#$#| $#$#$ |#$#$#| $#$$#$ |#$#| $#$#$#$ |#$#| $#$#$ #$$ |#| $#$#$#$#$ |#| #### |
使用锁定:$$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $ $$$$ | ##### | $$$$$ | ##### |