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,你會得到這樣的東西:

沒有鎖定:$#$#$#$#$#| $ |#$#$#$#$#| $$ |#$#$#$#| $#$ |#$#$#$#| $ $#$ |#$#$#| $#$#$ |#$#$#| $#$$#$ |#$#| $#$#$#$ |#$#| $#$#$ #$$ |#| $#$#$#$#$ |#| #### |

使用鎖定:$$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $$$$$ | ##### | $ $$$$ | ##### | $$$$$ | ##### |