简体   繁体   中英

Java Multithreading two classes in main

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

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

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM