Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在两个单独的JavaFx文本区域中显示两个不同线程的输出';s_Java_Multithreading_Javafx_Task - Fatal编程技术网

在两个单独的JavaFx文本区域中显示两个不同线程的输出';s

在两个单独的JavaFx文本区域中显示两个不同线程的输出';s,java,multithreading,javafx,task,Java,Multithreading,Javafx,Task,大家好,我必须制作两个线程,同时销售火车票,并在两个不同的窗口上显示输出,我已经创建了一个类来生成票证和Runnable,但我不确定如何在两个不同的文本区域框中显示两个不同线程的输出我已经尝试传递TextBox参数,但没有任何效果,请 SellTicketThreadProc: public class SellTicketThreadProc implements Runnable { private CTicketBiz cTicketBiz; public SellTic

大家好,我必须制作两个线程,同时销售火车票,并在两个不同的窗口上显示输出,我已经创建了一个类来生成票证和Runnable,但我不确定如何在两个不同的文本区域框中显示两个不同线程的输出我已经尝试传递TextBox参数,但没有任何效果,请

SellTicketThreadProc:

public class SellTicketThreadProc implements Runnable {
    private CTicketBiz cTicketBiz;

    public SellTicketThreadProc(CTicketBiz newobj){
        cTicketBiz = newobj;
    }

    public  void sellticket(){
        String color;
        switch(Thread.currentThread().getName()){
            case "Thread 1":
                color = ThreadColor.ANSI_CYAN;
                break;
            case "Thread 2":
                color = ThreadColor.ANSI_PURPLE;
                break;
            default:
                color = ThreadColor.ANSI_GREEN;
        }

        System.out.println(color + Thread.currentThread().getName() + " Random number: " + cTicketBiz.GetRandTicket() + "  Remaining tickets are: " + cTicketBiz.GetBalanceNum() );


    }

    @Override
    public void run() {
        while (cTicketBiz.GetBalanceNum() != 0) {
            sellticket();
        }
    }
}
CTicketBiz:

public class CTicketBiz {

    private int[] m_pTicket; //Point to the array that saves the ticket information
    private int m_nSoldNum; // Sold ticket number
    private int m_nBalanceNum; // Remaining ticket number
    private int m_nTotalNum;



    // Generate the ticket. Initialize the movie ticket array.
    void GenerateTicket(int totalTickets){
        m_nTotalNum = totalTickets;
        m_pTicket = new int[m_nTotalNum];
        m_nBalanceNum = m_nTotalNum;
        m_nSoldNum = 0;
        for (int i = 0; i < m_nTotalNum; i++) {
            m_pTicket[i] = i + 1;
        }
    }


    // Get a ticket randomly
    public synchronized int GetRandTicket(){
        if (m_nBalanceNum <= 0)
            return 0;
        int temp = 0;
        do {
            temp = new Random().nextInt(m_pTicket.length);
        } while (m_pTicket[temp] == 0);
        m_pTicket[temp] = 0;
        m_nBalanceNum--;
        m_nSoldNum++;
        return temp + 1;
    }
    // Get the remaining ticket number
    int GetBalanceNum(){
        return m_nBalanceNum;

    }

}

下面是一个快速运行的应用程序,演示如何从后台线程更新2个单独的文本区域,就像您确保通读解释发生了什么的注释一样。显然,这与你的程序不完全一样,但我保留了核心概念

public class Main extends Application {

    private AtomicInteger totalTickets = new AtomicInteger(100);
    private boolean isSellingTickets = false;

    @Override
    public void start(Stage stage) {
        VBox vBoxContainer = new VBox();
        vBoxContainer.setAlignment(Pos.CENTER);
        vBoxContainer.setPrefSize(400,250);

        TextArea textAreaTop = new TextArea();
        TextArea textAreaBottom = new TextArea();
        vBoxContainer.getChildren().addAll(textAreaTop, textAreaBottom);

        Button controlSalesButton = new Button("Start Ticket Sales");
        controlSalesButton.setOnAction(event -> {
            if(isSellingTickets) {
                isSellingTickets = false;
                controlSalesButton.setText("Start Ticket Sales");
            }
            else {
                isSellingTickets = true;
                //I didn't name these threads because I never reference them again
                // of course create var name if you need them
                new Thread(() -> sellTickets(textAreaTop)).start();
                new Thread(() -> sellTickets(textAreaBottom)).start();

                // This is on the main Thread so no need for Platform.runLater(...)
                controlSalesButton.setText("Stop Ticket Sales");
            }

        });
        vBoxContainer.getChildren().add(controlSalesButton);

        stage.setScene(new Scene(vBoxContainer));
        stage.show();
    }

    private void sellTickets(TextArea textArea){//This Whole Function is on another thread don't forget about that
        while(isSellingTickets && totalTickets.get()>1) { //Continue selling tickets until you stop
            // And Make Sure there is tickets to sell

            //Platform.runLater(... is used to update the main thread by pushing updates to
            // the JavaFX Application Thread at some unspecified time in the future.
            Platform.runLater(() -> {
                textArea.appendText("SOLD Ticket Number:" + (int) (Math.random() * 1000 + 1000) + " \t"
                        + totalTickets.decrementAndGet() + " Left to sell\n");
            });

            try {
                Thread.sleep((int) (Math.random() * 1000 + 100));//Different selling speeds this is irrelevant
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

如果您有任何问题,请让我知道

这里有一个快速运行的应用程序,演示如何从后台线程更新2个单独的文本区域,就像您看到的那样,请确保通读解释发生了什么的注释。显然,这与你的程序不完全一样,但我保留了核心概念

public class Main extends Application {

    private AtomicInteger totalTickets = new AtomicInteger(100);
    private boolean isSellingTickets = false;

    @Override
    public void start(Stage stage) {
        VBox vBoxContainer = new VBox();
        vBoxContainer.setAlignment(Pos.CENTER);
        vBoxContainer.setPrefSize(400,250);

        TextArea textAreaTop = new TextArea();
        TextArea textAreaBottom = new TextArea();
        vBoxContainer.getChildren().addAll(textAreaTop, textAreaBottom);

        Button controlSalesButton = new Button("Start Ticket Sales");
        controlSalesButton.setOnAction(event -> {
            if(isSellingTickets) {
                isSellingTickets = false;
                controlSalesButton.setText("Start Ticket Sales");
            }
            else {
                isSellingTickets = true;
                //I didn't name these threads because I never reference them again
                // of course create var name if you need them
                new Thread(() -> sellTickets(textAreaTop)).start();
                new Thread(() -> sellTickets(textAreaBottom)).start();

                // This is on the main Thread so no need for Platform.runLater(...)
                controlSalesButton.setText("Stop Ticket Sales");
            }

        });
        vBoxContainer.getChildren().add(controlSalesButton);

        stage.setScene(new Scene(vBoxContainer));
        stage.show();
    }

    private void sellTickets(TextArea textArea){//This Whole Function is on another thread don't forget about that
        while(isSellingTickets && totalTickets.get()>1) { //Continue selling tickets until you stop
            // And Make Sure there is tickets to sell

            //Platform.runLater(... is used to update the main thread by pushing updates to
            // the JavaFX Application Thread at some unspecified time in the future.
            Platform.runLater(() -> {
                textArea.appendText("SOLD Ticket Number:" + (int) (Math.random() * 1000 + 1000) + " \t"
                        + totalTickets.decrementAndGet() + " Left to sell\n");
            });

            try {
                Thread.sleep((int) (Math.random() * 1000 + 100));//Different selling speeds this is irrelevant
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

如果您有任何问题,请让我知道

到底是什么不起作用?您是否在两个
TextArea
s中的任何一个上获得任何输出,或者根本没有输出?请与您的问题无关:请学习java命名约定并坚持这些约定。嗨,伙计们,如果代码不好或我还在学习的任何东西,并且控制台中有输出,但文本区域中没有输出,我很抱歉。我试图返回字符串并将其附加到TextArea,但由于两个线程都在使用该字符串,因此无效。@kleopatra完全注意到感谢您提供的反馈,您可能需要使
GetBalanceNum()
同步。非同步方法不能保证看到其他线程对变量所做的更改。看,到底是什么不起作用?您是否在两个
TextArea
s中的任何一个上获得任何输出,或者根本没有输出?请与您的问题无关:请学习java命名约定并坚持这些约定。嗨,伙计们,如果代码不好或我还在学习的任何东西,并且控制台中有输出,但文本区域中没有输出,我很抱歉。我试图返回字符串并将其附加到TextArea,但由于两个线程都在使用该字符串,因此无效。@kleopatra完全注意到感谢您提供的反馈,您可能需要使
GetBalanceNum()
同步。非同步方法不能保证看到其他线程对变量所做的更改。看见