简体   繁体   English

Java - 如何为多线程同步运行 function

[英]Java - How to run function synchronously for multiple threads

I must use three instances of the Runnable class named changeCase and only one single instance of the Server class for all three changeCase instances.对于所有三个changeCase实例,我必须使用三个名为changeCaseRunnable class 实例,并且只使用一个Server class 实例。 The process execution needs to run continously, that is why I have used while (true) inside the overridden run method.流程执行需要连续运行,这就是我在覆盖的run方法中使用while (true)的原因。 The process method execution for each Thread is overlapping.每个线程的process方法执行是重叠的。 How can I solve this issue?我该如何解决这个问题?

My code:我的代码:

package uppercase;

import java.util.Scanner;

class Server {

    void process(String threadName) {

        System.out.println("You are inside the Server " +threadName);

        System.out.println("Enter your sentence");
        Scanner sc1 = new Scanner(System.in);
        String input = sc1.nextLine();

        System.out.println("Press 1 to convert to Uppercase or Press 2 to convert to Lowercase");
        Scanner sc2 = new Scanner(System.in);
        int num = sc2.nextInt();

        switch (num) {
            case 1:
                changetoUpperCase(input);
                break;
            case 2:
                changetoLowerCase(input);
                break;
            default:
                System.out.println("Invalid number given\n\n");
                break;
        }
    }

    void changetoUpperCase(String msg) {

        printMessage(msg.toUpperCase());
    }

    void changetoLowerCase(String msg) {

        printMessage(msg.toLowerCase());
    }

    void printMessage(String msg) {

        System.out.println("[ " +msg+ " ]\n\n");

        try {
            Thread.sleep(1000);
        }catch (Exception e) {
           System.out.println(e.getMessage());
        }
    }
}

class changeCase implements Runnable {

    String threadName;
    Server target;
    Thread t;

    public changeCase(Server c, String s) {

        this.threadName = s;
        this.target = c;
    }

    @Override
    synchronized public void run() {

        while(true) {

            target.process(threadName);
        }

        //target.process(threadName);
    }

}

public class UpperCase {

    public static void main(String[] args) {

        Server s1 = new Server();

        Thread t1 = new Thread(new changeCase(s1, "Thread1"));
        Thread t2 = new Thread(new changeCase(s1, "Thread2"));
        Thread t3 = new Thread(new changeCase(s1, "Thread3"));

        t1.start();
        t2.start();
        t3.start();
    }

}

The output I need:我需要的 output:

run:
You are inside the Server Thread1
Enter your sentence
hello world
Press 1 to convert to Uppercase or Press 2 to convert to Lowercase
1
[ HELLO WORLD ]


You are inside the Server Thread3
Enter your sentence
HELLO WORLD
Press 1 to convert to Uppercase or Press 2 to convert to Lowercase
2
[ hello world ]


You are inside the Server Thread2
Enter your sentence
hello world
Press 1 to convert to Uppercase or Press 2 to convert to Lowercase
4
Invalid number given


You are inside the Server Thread3
Enter your sentence

The output I am getting: output 我得到:

run:
You are inside the Server Thread1
Enter your sentence
You are inside the Server Thread2
Enter your sentence
You are inside the Server Thread3
Enter your sentence

Declare your method as below and it should work just fine.如下声明您的方法,它应该可以正常工作。

    @Override
    public void run() {

        while(true) {
            synchronized (target)
            {
                target.process(threadName);
                try {
                    target.wait();
                    notifyAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

Since you do not want to make process() method as synchronized , so I placed synchronized keyword in run() method.由于您不想将process()方法设置为synchronized ,因此我在run()方法中放置了synchronized关键字。

Why it should work just fine :为什么它应该工作得很好

  • The synchronised around the process() method call, allows only one Thread to access it at a time.围绕process()方法调用的synchronised ,一次只允许一个Thread访问它。
  • Passing the target object in synchronized keyword as that is the resource that threads are working on.synchronized关键字中传递target object,因为这是线程正在处理的资源。
  • Once you have utilised the resource ie the process() method is executed, need to wait() on the current Thread processing and notifyAll() other threads to take ownership.一旦你利用了资源,即process()方法被执行,需要在当前Thread处理上wait()notifyAll()其他线程取得所有权。
  • Calling target.wait() and not simply wait() because that uis the resource that threads are working on, otherwise it will throw java.lang.IllegalMonitorStateException: current thread is not owner .调用target.wait()而不仅仅是wait()因为那是线程正在处理的资源,否则它将抛出java.lang.IllegalMonitorStateException: current thread is not owner

Hope it answers your query.希望它能回答您的查询。

You can go through some resources here.您可以通过这里的一些资源 go。 https://www.geeksforgeeks.org/synchronized-in-java/ https://www.geeksforgeeks.org/synchronized-in-java/

You can use a counter to make thread execute one by one.您可以使用计数器使线程一个一个地执行。

class Server {
int threadCount = 3;
volatile int i = 1;

synchronized void process(String threadName) {
    int thread = Integer.parseInt(threadName.substring(threadName.length() - 1));
    if (thread % threadCount != i) {
        return;
    }
    i = i == threadCount - 1 ? 0 : i + 1;

    System.out.println("You are inside the Server " + threadName);

    System.out.println("Enter your sentence");
    Scanner sc1 = new Scanner(System.in);
    String input = sc1.nextLine();
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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