首页 > 解决方案 > Java多线程在main中的两个类

问题描述

我对编程很陌生,我正在尝试使用下面显示的Timer和类编写一个 Java 程序。ChecksUserInput如何让他们在主课中同时运行?

我也有打印出单词长度的问题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);
    }
}

标签: javamultithreadingsynchronize

解决方案


Java中多线程的基础是Thread类。使用的一般结构是:

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();
    }

超出这一点,问题开始变得更加复杂/上下文相关。前任:

  1. 在 2 个线程中运行的进程如何相互通信?
  2. 在 2 个线程中运行的进程如何访问/修改它们之间的公共状态?

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

样本:

    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(); }
    }

推荐阅读