Java 在 main 中多线程两个 类

Java Multithreading two classes in main

我是编程的新手,我正在尝试使用如下所示的 TimerChecksUserInput classes 编写 Java 程序。我如何让他们在主 class 中同时到达 运行?

我在打印 ChecksUserInput 中的字长时也遇到了问题。

main.java:

package application;

public class Main {
    public static void main(String[] args) {
        CreateBoard board = new CreateBoard();
        board.run();

        Timer timer = new Timer();
        timer.run();

        ChecksUserInput input = new ChecksUserInput();
        input.run();
    }
}

timer.java:

package application;

public class Timer {
    private static void time() {
        final int mili = 1000;
        final int sec = 60;
        final int oneMinute = (mili * sec);

        System.out.println("Start 3 minute timer");
        sleep(oneMinute * 2);

        System.out.println("One minute remaining...");
        sleep(oneMinute);

        System.out.println("Time's up!");
    }

    private static void sleep(int sleepTime) {
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        time();
    }
}

checksuserinput.java:

package application;

import java.util.*;

public class ChecksUserInput {
    private static String UserInput() {
        Scanner sc = new Scanner(System.in);
        System.out.println("Begin entering words!");

        String word = null;
        for (int i = 0; i < 10000; i++) {
            word = sc.nextLine();
        }

        return word;
    }

    private static int length(String word) {
        int wordLength = word.length();
        return wordLength;
    }

    public void run() {
        String userWord = UserInput();
        int wordLength = length(userWord);
        System.out.println(wordLength);
    }
}

您应该在您最喜欢的搜索引擎上搜索“java 多线程”并将您的代码与这些示例进行比较

你会发现这些人(大部分)在他们的 classes 上实现了 Runnable 接口。 所以

-- public class ChecksUserInput {

++ public class ChecksUserInput 实现 Runnable{

而 运行() 是该接口的一个方法,他们必须实现。

您的版本首先 运行 是第一个 class 的 运行 方法,然后是另一个。 但是当你实现 运行nable 接口时,这两个 运行 方法将一个接一个地被调用,而不是等待第一个完成

您应该自己搜索并找到更多示例,或者如果您遇到任何其他问题,请查看多线程文档

所以在@BATIKAN BORA ORMANCI 和@mike1234569 给了我很好的帮助之后 link https://www.geeksforgeeks.org/multithreading-in-java/ 我终于弄明白了

打包申请;

public class 主 {

public static void main(String[] args) {

    CreateBoard board = new CreateBoard();
    board.run();

    Thread timer = new Thread(new Timer());
    Thread input = new Thread(new ChecksUserInput());

    timer.start();
    input.start();

    try {
        timer.join();
        input.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}

并且我将 classes 设置为按照 Batikan 的建议实施 Runnable

Java 中 multi-threading 的基础是线程 class。使用的一般结构是:

Thread newProcess = new Thread(processToRun); //Create a thread which will execute the process
newProcess.setDaemon(true/false); //when false, the thread will keep the JVM alive beyond completion of 'main'
newProcess.start(); //Start processToRun in a new thread

要启动几个独立的进程,这应该足够了。例如,下面启动 10 个线程,每个线程将在循环中打印索引。最后,进程休眠 5 毫秒,因为生成的线程是守护进程。删除它可能会导致进程在打印任何消息之前终止。

    public static void main(String args[]) throws Exception
    {
        for(int i = 0; i < 10; i++) { int index = i; start(() -> System.out.println(index)); }
        Thread.sleep(5);
    }

    public static void start(Runnable processToRun)
    {
        Thread newProcess = new Thread(processToRun);
        newProcess.setDaemon(true);
        newProcess.start();
    }

除此之外,问题开始变得更多 complicated/contextual。例如:

  1. 2个线程中的进程运行如何相互通信?
  2. 2 个线程 access/modify 中的进程 运行 如何在它们之间共享状态?

在创建简单游戏的上下文中,一种选择是使用队列将用户输入提供给游戏并让游戏进程在单个线程中更新。以下示例在主线程上侦听用户输入的命令(上、下、左、右),并将有效命令添加到队列中。在不同的线程中轮询和处理有效命令以更新板上的位置。

样本:

    public static void main(String args[])
    {
        Board board = new Board();
        BlockingQueue<Move> movesQueue = new ArrayBlockingQueue<>(100);
        Scanner systemListener = new Scanner(System.in);
        start(() -> routeBoardMovesToQueue(board, movesQueue)); /*route moves from the queue to the board in a new thread*/
        while(true)
        {
            Optional<Move> nextMove = Move.resolve(systemListener.nextLine());
            if(nextMove.isPresent())
                movesQueue.offer(nextMove.get()); /*Write moves from System.in to the queue*/
            else
                System.out.println("Invalid Move Provided");
        }
    }
    
    public static void routeBoardMovesToQueue(Board board, BlockingQueue<Move> movesQueue)
    {
        try
        {
            while(true)
            {
                Move next = movesQueue.poll(100_000, TimeUnit.DAYS);
                if(next != null) board.performMove(next);
            }
        }
        catch(InterruptedException ignored){ System.out.println("Stopping"); }
    }

    public static void start(Runnable processToRun)
    {
        Thread newProcess = new Thread(processToRun);
        newProcess.setDaemon(true);
        newProcess.start();
    }

    public static final class Board
    {
        private final Location location;
        public Board(){ this.location = new Location(); }
        public void performMove(Move move)
        {
            switch(move)
            {
                case Up:    location.y += 1; break;
                case Down:  location.y -= 1; break;
                case Right: location.x += 1; break;
                case Left:  location.x -= 1; break;
            }
            System.out.println("New Position: (" + location.x + ", " + location.y + ")");
        }

        public static class Location{ int x = 0; int y = 0; }
    }

    public enum Move
    {
        Up, Down, Left, Right;
        public static Optional<Move> resolve(String move){ return Stream.of(Move.values()).filter(mv -> Objects.equals(move, mv.name())).findAny(); }
    }