繁体   English   中英

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

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

对于所有三个changeCase实例,我必须使用三个名为changeCaseRunnable class 实例,并且只使用一个Server class 实例。 流程执行需要连续运行,这就是我在覆盖的run方法中使用while (true)的原因。 每个线程的process方法执行是重叠的。 我该如何解决这个问题?

我的代码:

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

}

我需要的 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

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

如下声明您的方法,它应该可以正常工作。

    @Override
    public void run() {

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

由于您不想将process()方法设置为synchronized ,因此我在run()方法中放置了synchronized关键字。

为什么它应该工作得很好

  • 围绕process()方法调用的synchronised ,一次只允许一个Thread访问它。
  • synchronized关键字中传递target object,因为这是线程正在处理的资源。
  • 一旦你利用了资源,即process()方法被执行,需要在当前Thread处理上wait()notifyAll()其他线程取得所有权。
  • 调用target.wait()而不仅仅是wait()因为那是线程正在处理的资源,否则它将抛出java.lang.IllegalMonitorStateException: current thread is not owner

希望它能回答您的查询。

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

您可以使用计数器使线程一个一个地执行。

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