JavaFX 8 中的线程同步问题

问题描述 投票:0回答:0

我正在使用 JavaFX 8,我有一个奇怪的问题,无论我尝试什么,我都无法让线程同步。

我正在构建的代码需要从屏幕左侧到右侧显示图像。在控制台中提示用户他们想要多少赛车手。当其中一个到达终点线时,所有线程都停止,并且必须在屏幕左侧设置标签,在赛车手比赛的路径上。

线程成功停止,我还没有实现设置标签(如果有人能帮忙的话,这也很好)因为我无法获得正确的线程来将获胜者号码打印到终端。

代码如下:

import java.util.ArrayList;
import java.util.Scanner;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class Races extends Application {

    Scanner in = new Scanner(System.in);

    Stage stage;
    Scene scene;

    VBox root;
    Line finishLine;

    Image imgRacer;

    boolean keepGoing = true;

    public final int DEFAULT_RACERS = 5;
    ArrayList<Thread> threadList = new ArrayList<>();
    ArrayList<Pane> paneList = new ArrayList<>();
    ArrayList<RaceStarter> racerList = new ArrayList<>();

    @Override
    public void start(Stage stage) throws Exception {
        this.stage = stage;
        stage.setTitle("Off to the races");

        root = new VBox(0);

        int numRacers = DEFAULT_RACERS;

        imgRacer = new Image(new FileInputStream("embars.gif"));
        double imgHeight = imgRacer.getHeight();
        double imgWidth = imgRacer.getWidth();

        System.out.print("How many racers do you want? (Default 5): ");
        if(in.hasNextInt()){
            numRacers = in.nextInt();
            if(numRacers < 1) numRacers = DEFAULT_RACERS;
        }
        for(int i = 0; i < numRacers; i++) {
            RaceStarter racer = new RaceStarter(i, imgWidth, imgHeight);
            paneList.add(racer);
            Thread t = new Thread(racer);
            threadList.add(t);
            t.start();
        }

        scene = new Scene(root, imgWidth * 20, imgHeight * numRacers);

        finishLine = new Line(scene.getWidth() - (imgWidth * 2), 0, scene.getWidth() - (imgWidth * 2), scene.getHeight());
        finishLine.setStrokeWidth(2);
        finishLine.setStroke(Paint.valueOf("BLACK"));

        Pane finishPane = new Pane(finishLine);
        root.getChildren().add(finishPane);

        stage.setScene(scene);
        stage.show();

    }
    public static void main(String[] args) throws Exception {
        launch(args);
    }
    
    class RaceStarter extends Pane implements Runnable{

        int racerNum;
        double height, width;

        volatile boolean finished = false;

        private Object lock = new Object();

        public RaceStarter(int racerNum, double width, double height){
            this.racerNum = racerNum;
            this.width = width;
            this.height = height;
        }

        @Override
        public void run() {

            System.out.println(Thread.currentThread() + " " + racerNum);

            ImageView racer = new ImageView(imgRacer);

            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    root.getChildren().add(racer);
                }
            });

            while(keepGoing) {
                // System.out.println(name);
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                double moveAmount = Math.random() * 5;
                
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        racer.setTranslateX(racer.getTranslateX() + moveAmount);
                    }
                });
                synchronized(paneList){
                    if(racer.getTranslateX() >= width * 17){
                        keepGoing = false;
                        this.finished = true;
                        System.out.println("Winner is racer #" + (this.racerNum+1));
                        Label lblWinner = new Label("Winner is racer #" + (this.racerNum+1));
                        Platform.runLater(new Runnable() {
                            @Override
                            public void run() {
                                paneList.get(racerNum).getChildren().add(0, lblWinner);
                            }
                        });
                    }
                }

            }
        }
    }
}```
java multithreading java-8 synchronization javafx-8
© www.soinside.com 2019 - 2024. All rights reserved.