问题描述
我对编程非常陌生,我正在尝试使用下面显示的Timer
和ChecksUserInput
类编写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();
}
除此之外,问题开始变得更加复杂/具体。例如:
- 在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(); }
}