在作家阅读器中使用信号量

时间:2016-11-29 12:14:37

标签: java multithreading semaphore

所以我参加了多线程开发课程,目前正在学习信号量。在我们最新的作业中,我们应该使用三个线程和两个队列。编写器线程将chars写入第一个队列,然后是#34;加密器"线程将从该队列中读取字符,加密char然后将其添加到第二个队列。然后我们有一个读取器线程从第二个队列中读取。为了处理同步,我们应该使用信号量和互斥量,但我没有任何管理:

public class Buffer {
private Queue<Character> qPlain = new LinkedList<Character>();
private Queue<Character> qEncrypt = new LinkedList<Character>();
private final int CAPACITY = 3;

public Buffer() {
    System.out.println("New Buffer!");
}

public synchronized void addPlain(char c) {
    while (qPlain.size() == CAPACITY) {
        try {
            wait();
            System.out.println("addPlain is waiting to add Data");
        } catch (InterruptedException e) {
        }
    }
    qPlain.add(c);
    notifyAll();
    System.out.println("addPlain Adding Data-" + c);
}

public synchronized char removePlain() {
    while (qPlain.size() == 0) {
        try {
            wait();
            System.out.println("----------removePlain is waiting to return Data.");
        } catch (InterruptedException e) {
        }
    }
    notifyAll();
    char c = qPlain.remove();
    System.out.println("---------------removePlain Returning Data-" + c);
    return c;
}

public synchronized void addEncrypt(char c) {
    while (qEncrypt.size() == CAPACITY) {
        try {
            wait();
            System.out.println("addEncrypt is waiting to add Data");
        } catch (InterruptedException e) {
        }
    }

    qEncrypt.add(c);
    notifyAll();
    System.out.println("addEncrypt Adding Data-" + c);
}

public synchronized char removeEncrypt() {
    while (qEncrypt.size() == 0) {
        try {
            wait();
            System.out.println("----------------removeEncrypt is waiting to return Data.");
        } catch (InterruptedException e) {
        }
    }
    notifyAll();
    char c = qEncrypt.remove();
    System.out.println("--------------removeEncrypt Returning Data-" + c);
    return c;
}

}

所以这个工作正常,但我不会通过,因为我没有使用任何信号量。我理解这个概念,但在这种情况下,我只是没有看到使用任何一个的观点。我有2个队列,每个队列只有一个读者和作者。

编辑:改为使用信号量更新。它几乎可以工作,当队列为空时调用removePlain()方法时会出现问题。我很确定我应该阻止它,但我在这里迷了路。我可以不只是在这里使用互斥量吗?

public class Buffer {
private Semaphore encryptedSem = new Semaphore(0);
private Semaphore decryptedSem = new Semaphore(0);
private final Queue<Character> qPlain = new LinkedList<Character>();
private final Queue<Character> qEncrypt = new LinkedList<Character>();
private final int CAPACITY = 3;
private boolean startedWrite = false;
private boolean startedRead = false;

/**
 * Adds a character to the queue containing non encrypted chars.
 * 
 * @param c
 */
public void addPlain(char c) {

    // Makes sure that this writer executes first.
    if (!startedWrite) {
        startedWrite = true;
        encryptedSem = new Semaphore(1);
    }

    if (qPlain.size() < CAPACITY) {
        aquireLock(encryptedSem);
        System.out.println("addPlain has lock");
        qPlain.add(c);
        realeseLock(encryptedSem);
    }
}

/**
 * Removes and returns the next char in the non encrypted queue.
 * 
 * @return
 */
public char removePlain() {
    // TODO Need to fix what happens when the queue is 0. Right now it just
    // returns a char that is 0. This needs to be blocked somehow.

    char c = 0;

    if (qPlain.size() > 0) {
        aquireLock(encryptedSem);
        System.out.println("removePlain has lock");
        c = qPlain.remove();
        realeseLock(encryptedSem);
    } else {
        System.out.println("REMOVEPLAIN CALLED WHEN qPlain IS EMPTY");
    }
    return c;
}

/**
 * Adds a character to the queue containing the encrypted chars.
 * 
 * @param c
 */
public void addEncrypt(char c) {
    if (!startedRead) {
        startedRead = true;
        decryptedSem = new Semaphore(1);
    }

    if (qEncrypt.size() < CAPACITY) {
        aquireLock(decryptedSem);
        System.out.println("addEncrypt has lock");
        qEncrypt.add(c);
        realeseLock(decryptedSem);
    }

}

/**
 * Removes and returns the next char in the encrypted queue.
 * 
 * @return
 */
public char removeEncrypt() {
    char c = 0;
    if (qEncrypt.size() > 0) {
        aquireLock(decryptedSem);
        System.out.println("removeEncrypt has lock");
        c = qEncrypt.remove();
        realeseLock(decryptedSem);

    }
    return c;
}

/**
 * Aquries lock on the given semaphore.
 * 
 * @param sem
 */
private void aquireLock(Semaphore sem) {
    try {
        sem.acquire();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

/**
 * Realeses lock on the given semaphore.
 * 
 * @param sem
 */
private void realeseLock(Semaphore sem) {
    sem.release();
}

}

0 个答案:

没有答案