所以我的代码就像我想要的那样工作我唯一的问题就是这个......基本上我有一个主要类来控制铁路轨道上的大门,当火车接近或越过轨道时门应该关闭的两个轨道中的一个。我遇到的唯一问题是当门打开或关闭垃圾邮件时的声明,例如每当它执行某些操作时会发生3-5次垃圾邮件,如果关闭它将会发生...
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closed
我想知道为什么会发生这种情况,这是我的Gate类和Main类的代码
public class Gate {
private boolean isClosed = false;
private boolean closing = false;
private boolean opening = false;
public Gate(){
}
public void close(){
if(!(isClosing() == true)){
Runnable task = new Runnable() {
public void run() {
try {
setClosing(true);
setOpening(false);
System.out.println("GATE: Closing");
Thread.sleep(400);
System.out.println("GATE: Closed");
setClosed(true);
setClosing(false);
}catch(Exception ex){
}
}
};
new Thread(task, "closeThread").start();
}
}
public void open(){
if(!(isOpening() == true)){
Runnable task = new Runnable() {
public void run() {
try {
setOpening(true);
System.out.println("GATE: Opening");
Thread.sleep(400);
setOpening(false);
if(closing == false){
setClosed(false);
System.out.println("GATE: Opened");
}
}catch(Exception ex){
}
}
};
new Thread(task, "openThread").start();
}
}
public boolean isClosed(){
return isClosed;
}
public boolean isClosing(){
return closing;
}
public boolean isOpening(){
return opening;
}
public synchronized void setClosing(boolean t){
closing = t;
}
public synchronized void setOpening(boolean t){
opening = t;
}
public synchronized void setClosed(boolean t){
isClosed = t;
}
}
public class Controller {
public static void main(String[] args){
Track t1 = new Track("Track 1");
Track t2 = new Track("Track 2");
Gate g = new Gate();
t1.simulateTrack();
t2.simulateTrack();
do{
System.out.print("");
if((t1.isApproaching() || t1.isCrossing()) || (t2.isApproaching() || t2.isCrossing())){
if(!g.isClosed() && !g.isClosing()){
g.close();
}
}else if(g.isClosed() && !g.isOpening()){
g.open();
}
}while((t1.isSimulating() || t2.isSimulating()));
}
}
还有Track的代码
import java.security.SecureRandom;
public class Track {
private static final SecureRandom gen = new SecureRandom() ;
private boolean approaching = false;
private boolean atCrossing = false;
private boolean simulating = false;
private String trackName = "";
public Track(String n){
trackName = n;
}
public void simulateTrack(){
Runnable task = new Runnable() {
public void run() {
try {
setSimulating(true);
for(int i = 0; i < 10; i++){
Thread.sleep((gen.nextInt(5000) + 2500));
setApproaching(true);
System.out.println(trackName + ": Train is now approaching.");
Thread.sleep((gen.nextInt(5000) + 3500));
setCrossing(true);
setApproaching(false);
System.out.println(trackName + ": Train is now crossing.");
Thread.sleep((gen.nextInt(1000) + 1000));
setCrossing(false);
System.out.println(trackName + ": Train has left.");
}
setSimulating(false);
} catch (Exception ex) {
}
}
};
new Thread(task, "simulationThread").start();
}
public boolean isApproaching(){
return approaching;
}
public boolean isCrossing(){
return atCrossing;
}
public boolean isSimulating(){
return simulating;
}
public synchronized void setSimulating(boolean t){
simulating = t;
}
public synchronized void setApproaching(boolean t){
approaching = t;
}
public synchronized void setCrossing(boolean t){
atCrossing = t;
}
}
答案 0 :(得分:1)
这只是一个想法:
通过在后台线程上拍摄close()
逻辑,您将失去原子性。 main
的{{1}}循环可以放弃5次,然后放弃对主线程的控制,其中一个“closeThread”开始执行。你不会看到多个“GATE:Closed”吗?
试试这个(未经测试,抱歉):
do
您需要以相同的方式修改public synchronized void close() { // added synchornized
if (!isClosing()) { // read: "if not closing"
setClosing(true); // set closing so next time close() is called it is a no op
setOpening(false); // close other loopholes so the state is correct
System.out.println("GATE: Closing");
// we're in closing state now, because the close method is almost finished
// start the actual closing sequence
Runnable task = new Runnable() {
public void run() {
try {
Thread.sleep(400);
System.out.println("GATE: Closed");
setClosed(true);
setClosing(false);
}catch(Exception ex){
}
}
};
new Thread(task, "closeThread").start();
}
}
,以便始终保留不变量。检查和设置open()
和closing
标记是互斥的,这就是将opening
放在这两个标记上所得到的。