Java多线程主类中的两个类

huangapple go评论76阅读模式
英文:

Java Multithreading two classes in main

问题

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

I am very new to programming, and I am trying to write a Java program with the Timer and ChecksUserInput classes shown below. How do I get them to run at the same time in the main class?

I am also having issues with printing out the word length in 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(&quot;Start 3 minute timer&quot;);
        sleep(oneMinute * 2);

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

        System.out.println(&quot;Time&#39;s up!&quot;);
    }

    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(&quot;Begin entering words!&quot;);

        String word = null;
        for (int i = 0; i &lt; 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);
    }
}

答案1

得分: 0

你应该在你喜欢的搜索引擎上搜索"java多线程编程",然后将你的代码与这些示例进行比较。

你会发现这些人大多数情况下都在他们的类上实现了Runnable接口。
所以

-- public class ChecksUserInput {

++ public class ChecksUserInput implements Runnable{

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

你的版本首先运行第一个类的run方法,然后运行另一个类的run方法。
但是当你实现了Runnable接口后,两个run方法将会连续调用,而不会等待第一个方法完成。

你应该自己搜索并找到更多的示例,或者在面对其他问题时查阅多线程的文档。

英文:

You should search "java multithreading" on your favourite search engine and compare your code with those examples

You will find that these people have (mostly) implemented the Runnable interface on their classes.
So

-- public class ChecksUserInput {

++ public class ChecksUserInput implements Runnable{

And run() was a method of that interface, that they had to implement.

Your version first runs the run method of the first class, then the other.
But when you implement the runnable interface, the both run methods will be called right after one another, without waiting for the first one to finish

You should search on your own and find more examples, or check the documentations for multithreading if you face any other issues

答案2

得分: 0

在经过@BATIKAN BORA ORMANCI和@mike1234569的精彩帮助以及这个链接https://www.geeksforgeeks.org/multithreading-in-java/的指导后,我实际上能够弄清楚它。

package application;

public class Main {

    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接口。

英文:

So after the wonderful help @BATIKAN BORA ORMANCI and @mike1234569 gave me along with this link https://www.geeksforgeeks.org/multithreading-in-java/ I was able to actually figure it out

package application;

public class Main {

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

}

and I set my classes to implement Runnable as Batikan suggested

答案3

得分: 0

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

Thread newProcess = new Thread(processToRun); // 创建一个线程,它将执行该进程
newProcess.setDaemon(true/false); // 当为false时,线程将在'main'完成后保持JVM的活动状态
newProcess.start(); // 在新线程中启动processToRun

要启动多个独立的进程,这应该就足够了。例如,以下代码启动了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)两个线程中运行的进程如何访问/修改它们之间的共享状态?

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

示例:

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)); /*将移动从队列中路由到新线程中的板*/
    while(true)
    {
        Optional<Move> nextMove = Move.resolve(systemListener.nextLine());
        if(nextMove.isPresent())
            movesQueue.offer(nextMove.get()); /*将从System.in接收到的移动写入队列*/
        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(); }
}
英文:

The foundation of multi-threading in Java is the Thread class. The general structure for usage is:

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 &#39;main&#39;
newProcess.start(); //Start processToRun in a new thread

To start several independent processes, this should be sufficient. For example, the following starts 10 threads each of which will print the index in the loop. At the end, the process sleeps for 5 milliseconds because the spawned threads are daemon. Removing this may cause the process to terminate before any messages are printed.

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

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

Beyond this point questions start to get more complicated/contextual. Ex:

  1. How can processes running in 2 threads communicate with each other?
  2. How can processes running in 2 threads access/modify common state between them?

In the context of creating a simple game, one option is to use Queues to feed user inputs to the game and have the game process updates in a single thread. The following sample listens for the user inputting commands (Up, Down, Left, Right) on the main thread and adds valid commands to a queue. Valid commands are polled and processed in a different thread to update the location on the board.

Sample:

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

	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(&quot;New Position: (&quot; + location.x + &quot;, &quot; + location.y + &quot;)&quot;);
		}

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

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

huangapple
  • 本文由 发表于 2020年9月19日 04:08:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63962233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定