【问题标题】:Java Semaphore, acquire() and release()Java 信号量,acquire() 和 release()
【发布时间】:2019-12-23 00:11:25
【问题描述】:

我是 java 的初学者,我正在试验 Semaphore。 我试图写一个有作家和读者的代码,我只尝试使用acquire()和release():

1) 如果一个作家正在写作,那么同时没有其他作家可以写作,也没有读者可以阅读。
2)多个阅读器可以同时阅读,但如果至少有一个活动阅读器,那么作者就不能写任何东西。

所以,总而言之,可以有
- 一个读者,没有作家
- 多个读者,没有作家
- 一个作家没有读者

我尝试编写下面的代码,我知道它可能非常糟糕,但我真的很难理解这个概念并且代码不起作用,我不知道如何修复它。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class Main 
{


    public static void main(String [] args) 
    {
        ExecutorService executorService = Executors.newCachedThreadPool();
        ReadWriteLock RW = new ReadWriteLock();

        executorService.execute(new Writer(RW));
        executorService.execute(new Writer(RW));
        executorService.execute(new Writer(RW));
        executorService.execute(new Writer(RW));

        executorService.execute(new Reader(RW));
        executorService.execute(new Reader(RW));
        executorService.execute(new Reader(RW));
        executorService.execute(new Reader(RW));                
    }
}


class ReadWriteLock
{


    private int reader = 0;
    private Semaphore write = new Semaphore(1);

    public void readLock()  
    {           
        if (write.availablePermits() == 1)
        {
            reader++;
        }
    }

    public void writeLock() 
    {       
        if (write.availablePermits() == 1)
        {
            try 
            {
                write.acquire();
            } 
            catch(InterruptedException e)
            {
                e.printStackTrace();;
            }
        }

    }

    public void readUnLock() 
    {
         if (reader > 0)
            reader--;
    }

    public void writeUnLock() 
    {

        if (write.availablePermits() == 0)
        {
            write.release();
        }

    }

}




class Writer implements Runnable
{
   private ReadWriteLock RW_lock;


    public Writer(ReadWriteLock rw) {
        RW_lock = rw;
   }

    public void run() {
      while (true){
          RW_lock.writeLock();

          RW_lock.writeUnLock();

      }
   }


}



class Reader implements Runnable
{
   private ReadWriteLock RW_lock;


   public Reader(ReadWriteLock rw) {
        RW_lock = rw;
   }
    public void run() {
      while (true){               
          RW_lock.readLock();


          RW_lock.readUnLock();

      }
   }


} 

【问题讨论】:

    标签: java semaphore


    【解决方案1】:

    您可以按照以下使用信号量解决读写器问题的方法。它处理所有提到的条件并使用java.util.concurrent.Semaphore 包来实现信号量。 http://www2.hawaii.edu/~walbritt/ics240/synchronization/ReaderWriterSolution.java

    您必须在读取器和写入器上定义锁。以下是所有读卡器的接口。

    interface RWLock{
           public abstract void acquireReadLock(int readerNum);
           public abstract void acquireWriteLock(int writerNum);
           public abstract void releaseReadLock(int readerNum);
           public abstract void releaseWriteLock(int writerNum);
       }
    

    Database.java持有所有读写函数的定义:

    class Database implements RWLock{
          private int readerCount;  // the number of active readers
          private Semaphore mutex;  // controls access to readerCount
          private Semaphore db;     // controls access to the database
    
           public Database() {
             readerCount = 0;
             mutex = new Semaphore(1);
             db = new Semaphore(1);
          }
    
           public void acquireReadLock(int readerNum) {
             try{
             //mutual exclusion for readerCount 
                mutex.acquire();
             }
                 catch (InterruptedException e) {}
    
             ++readerCount;
    
          // if I am the first reader tell all others
          // that the database is being read
             if (readerCount == 1){
                try{
                   db.acquire();
                }
                    catch (InterruptedException e) {}
             }
    
             System.out.println("Reader " + readerNum + " is reading. Reader count = " + readerCount);
             //mutual exclusion for readerCount
             mutex.release();
          }
    
           public void releaseReadLock(int readerNum) {
             try{
             //mutual exclusion for readerCount
                mutex.acquire();
             }
                 catch (InterruptedException e) {}
    
             --readerCount;
    
          // if I am the last reader tell all others
          // that the database is no longer being read
             if (readerCount == 0){
                db.release();
             }
    
             System.out.println("Reader " + readerNum + " is done reading. Reader count = " + readerCount);
    
          //mutual exclusion for readerCount
             mutex.release();
          }
    
           public void acquireWriteLock(int writerNum) {
             try{
                db.acquire();
             }
                 catch (InterruptedException e) {}
             System.out.println("Writer " + writerNum + " is writing.");
          }
    
           public void releaseWriteLock(int writerNum) {
             System.out.println("Writer " + writerNum + " is done writing.");
             db.release();
          }
    
    
       }
    

    现在您需要分别实现读取器和写入器。通过获取锁并遵循上述条件:

    • 一个读者没有作者
    • 有多个读者,没有作者
    • 一个作者没有读者
    class Reader implements Runnable
       {
    
          private RWLock database;
          private int readerNum;
    
           public Reader(int readerNum, RWLock database) {
             this.readerNum = readerNum;
             this.database = database;
          }
    
           public void run() {
             while (true) {
                SleepUtilities.nap();
    
                System.out.println("reader " + readerNum + " wants to read.");
                database.acquireReadLock(readerNum);
    
             // you have access to read from the database
             // let's read for awhile .....
                SleepUtilities.nap();
    
                database.releaseReadLock(readerNum);
             }
          }
       ;
       }
    
       class Writer implements Runnable
       {
          private RWLock database;
          private int writerNum;
    
           public Writer(int w, RWLock d) {
             writerNum = w;
             database = d;
          }
    
           public void run() {
             while (true){
                SleepUtilities.nap();
    
                System.out.println("writer " + writerNum + " wants to write.");
                database.acquireWriteLock(writerNum);
    
             // you have access to write to the database
             // write for awhile ...
                SleepUtilities.nap();
    
                database.releaseWriteLock(writerNum);
             }
          }
    
    
       }
    

    最后你需要一个运行类来测试解决方案

    import java.util.concurrent.Semaphore;
    
        public class ReaderWriterSolution{
          public static final int NUM_OF_READERS = 3;
          public static final int NUM_OF_WRITERS = 2;
    
           public static void main(String args[]){
             RWLock database = new Database();
    
             Thread[] readerArray = new Thread[NUM_OF_READERS];
             Thread[] writerArray = new Thread[NUM_OF_WRITERS];
    
             for (int i = 0; i < NUM_OF_READERS; i++) {
                readerArray[i] = new Thread(new Reader(i, database));
                readerArray[i].start();
             }
    
             for (int i = 0; i < NUM_OF_WRITERS; i++) {
                writerArray[i] = new Thread(new Writer(i, database));
                writerArray[i].start();
             }
          }
       }
    

    所有类都已包含在解决方案中。 希望对您有所帮助!

    【讨论】:

      猜你喜欢
      • 2017-08-24
      • 1970-01-01
      • 2015-05-26
      • 2012-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      相关资源
      最近更新 更多