gpt4 book ai didi

Java异步问题

转载 作者:行者123 更新时间:2023-12-01 12:09:42 24 4
gpt4 key购买 nike

所以我的代码按照我想要的方式工作,我遇到的唯一问题是这个..基本上我有一个主类,当火车接近或穿过铁轨时,它控制铁轨上的大门大门应关闭的两条轨道之一。我遇到的唯一问题是当门打开或关闭垃圾邮件时的语句,每次它执行某项操作时都会执行 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;
}
}

最佳答案

这只是一个想法:通过在后台线程上执行 close() 逻辑,您将失去原子性。 maindo 循环在放弃对主线程的控制并且“closeThread”之一开始执行之前可以执行大约 5 次。您没有看到多个“GATE:已关闭”吗?

试试这个(未经测试,抱歉):

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(),以便始终保留不变量。检查和设置closeopening 标志是互斥的,这就是通过在它们上放置synchronized 得到的结果。

关于Java异步问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27336018/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com