Java多线程处理主要有两个类

问题描述

我对编程非常陌生,我正在尝试使用下面显示TimerChecksUserInput类编写Java程序。如何让它们在主类中同时运行?

在打印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 multithreading”,并将代码与这些示例进行比较

您会发现这些人(大部分)已经在其类上实现了Runnable接口。 所以

-公共类ChecksUserInput {

++公共类ChecksUserInput实现了Runnable {

run()是该接口的一种方法,他们必须实现。

您的版本首先运行第一个类的run方法,然后运行另一个类。 但是,当您实现runnable接口时,这两个run方法将彼此紧接着被调用,而无需等待第一个方法完成

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

,

因此,在@BATIKAN BORA ORMANCI和@ mike1234569给予了出色的帮助之后,我连同此链接https://www.geeksforgeeks.org/multithreading-in-java/一起真正找出了答案

打包申请;

公共类主要{

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

}

并且我设置了我的类以按照Batikan的建议实现Runnable

,

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