我在一项作业中被要求实现正确调用“ping”和“pong”(意思是在 ping 之前没有 pong)10 次的乒乓球游戏。意思是,控制台中的最终输出应该是:“ping!(1)”,“pong!(1)”,“ping!(2)”,“pong!(2)”等。
需求是用信号量、可重入锁和倒计时锁来实现gamepingpongthread。
我的问题是打印顺序并不总是按照要求,我想知道我做错了什么。
这是代码:
// Import the necessary Java synchronization and scheduling classes.
import java.util.concurrent.Semaphore;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
/**
* @class PingPongRight
*
* @brief This class implements a Java program that creates two
* instances of the PlayPingPongThread and start these thread
* instances to correctly alternate printing "Ping" and "Pong",
* respectively, on the console display.
*/
public class PingPongRight
{
/**
* @class SimpleSemaphore
*
* @brief This class provides a simple counting semaphore
* implementation using Java a ReentrantLock and a
* ConditionObject.
*/
static public class SimpleSemaphore
{
private int mPermits;
private ReentrantLock lock = new ReentrantLock();
private Condition isZero = lock.newCondition();
/**
* Constructor initialize the data members.
*/
public SimpleSemaphore (int maxPermits)
{
mPermits = maxPermits;
}
/**
* Acquire one permit from the semaphore.
*/
public void acquire() throws InterruptedException
{
lock.lock();
while (mPermits == 0)
isZero.await();
mPermits--;
lock.unlock();
}
/**
* Return one permit to the semaphore.
*/
void release() throws InterruptedException
{
lock.lock();
try {
mPermits++;
isZero.signal();
} finally {
lock.unlock();
}
}
}
/**
* Number of iterations to run the test program.
*/
public static int mMaxIterations = 10;
/**
* Latch that will be decremented each time a thread exits.
*/
public static CountDownLatch latch = new CountDownLatch(2);
/**
* @class PlayPingPongThread
*
* @brief This class implements the ping/pong processing algorithm
* using the SimpleSemaphore to alternate printing "ping"
* and "pong" to the console display.
*/
public static class PlayPingPongThread extends Thread
{
private String message;
private SimpleSemaphore semaphore;
/**
* Constructor initializes the data member.
*/
public PlayPingPongThread (String msg, SimpleSemaphore pingOrPong)
{
message = msg;
semaphore = pingOrPong;
}
/**
* Main event loop that runs in a separate thread of control
* and performs the ping/pong algorithm using the
* SimpleSemaphores.
*/
public void run ()
{
for (int i = 1 ; i <= mMaxIterations ; i++) {
try {
semaphore.acquire();
System.out.println(message + "(" + i + ")");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
latch.countDown();
}
}
/**
* The main() entry point method into PingPongRight program.
*/
public static void main(String[] args) {
try {
// Create the ping and pong SimpleSemaphores that control
// alternation between threads.
SimpleSemaphore pingSemaphore = new SimpleSemaphore(mMaxIterations);
SimpleSemaphore pongSemaphore = new SimpleSemaphore(mMaxIterations);
System.out.println("Ready...Set...Go!");
// Create the ping and pong threads, passing in the string
// to print and the appropriate SimpleSemaphores.
PlayPingPongThread ping = new PlayPingPongThread("Ping!", pingSemaphore);
PlayPingPongThread pong = new PlayPingPongThread("Pong!", pongSemaphore);
// Initiate the ping and pong threads, which will call the run() hook method.
ping.start();
pong.start();
// Use barrier synchronization to wait for both threads to finish.
latch.await();
}
catch (java.lang.InterruptedException e)
{}
System.out.println("Done!");
}
}
提前致谢
我的问题是打印顺序并不总是按照要求,我想知道我做错了什么。
我认为你的问题是 ping 和 pong 线程都在获取和释放自己的信号量。我认为你需要通过both两个线程的信号量。每个线程调用acquire()
on the acquireSemaphore
and release()
on the releaseSemaphore
.
acquireSemaphore.acquire();
System.out.println(message + "(" + i + ")");
releaseSemaphore.release();
该线程看起来像:
public PlayPingPongThread (String msg, SimpleSemaphore acquireSemaphore,
SimpleSemaphore releaseSemaphore)
然后线程被初始化为:
// ping acquires on the ping, releases the pong
PlayPingPongThread ping = new PlayPingPongThread("Ping!", pingSemaphore, pongSemaphore);
// pong acquires on the pong, releases the ping
PlayPingPongThread pong = new PlayPingPongThread("Pong!", pongSemaphore, pingSemaphore);
The pingSemaphore
应从 1 许可证开始,而 pong 许可证应从 0 开始。
-
ping
第一次通话acquire()
on the pingSemaphore
它被给予了。
-
ping
打印出 ping。
-
ping
calls release()
on the pongSemaphore
.
- 这一下醒了
pong
(当然假设你的信号量代码有效)。
-
pong
prints pong
.
-
pong
calls release()
on the pingSemaphore
.
- 重复...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)