正确实施乒乓游戏 [英] Implementing pingpong game correctly
问题描述
我在一项作业中被要求实施10次正确的乒乓球游戏,该游戏正确地调用了"ping"和"pong"(意思是在ping之前没有pong).意思是,控制台中的最终输出应该是:"ping!(1)","pong!(1)","ping!(2)","pong!(2)"等.
I'm requested in an assignment to implement pingpong game that called "ping" and "pong" correctly (meaning, no pong before ping) 10 times. Meaning, the final output in the console should be: "ping!(1)", "pong!(1)", "ping!(2)", "pong!(2)" etc.
需求是使用信号量,reetrantlock和倒数锁存器实现gamepingpongthread.
The demand is to implement gamepingpongthread with semaphores, reetrantlock and countdown latch.
我的问题是打印顺序并非总是按要求进行,我想知道我做错了什么.
My problem is that the print order is not always as requested, and I wonder what I'm doing wrong.
代码如下:
// 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!");
}
}
预先感谢
推荐答案
我的问题是打印顺序并非总是按要求进行,我想知道我做错了什么.
My problem is that the print order is not always as requested, and I wonder what I'm doing wrong.
我认为您的问题是ping和pong线程都正在获取和释放自己的信号量.我认为您需要将两个信号都传递给两个线程.每个线程调用 acquireSemaphore
上的 acquire()
和 releaseSemaphore
上的 release()
.
I think your problem is that both the ping and pong threads are acquiring and releasing their own semaphore. I think you need to pass both semaphores to both threads. Each thread calls 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);
pingSemaphore
应该以1个许可开始,而pong一个应该以0开始.
The pingSemaphore
should start with 1 permit and the pong one should start with 0.
-
ping
首先在pingSemaphore
上调用acquire()
并给出 . -
ping
打印出ping. -
ping
调用pongSemaphore
上的release()
. - 这会唤醒
pong
(当然,假设您的信号灯代码有效). -
pong
打印pong
. -
pong
在pingSemaphore
上调用release()
. - 重复...
ping
first callsacquire()
on thepingSemaphore
and it is given.ping
prints out ping.ping
callsrelease()
on thepongSemaphore
.- This wakes up
pong
(assuming your semaphore code works of course). pong
printspong
.pong
callsrelease()
on thepingSemaphore
.- repeat...
这篇关于正确实施乒乓游戏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!