Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从不同的线程按一定顺序打印行?_Java_Multithreading_Concurrency_Thread Safety - Fatal编程技术网

Java 如何从不同的线程按一定顺序打印行?

Java 如何从不同的线程按一定顺序打印行?,java,multithreading,concurrency,thread-safety,Java,Multithreading,Concurrency,Thread Safety,假设我们有一个类: 公共类Foo{ public void first(){print(“first”);} public void second(){print(“second”);} public void third(){print(“third”);} } 同一个Foo实例将传递给三个不同的线程。线程A将调用first(),线程B将调用second(),线程C将调用third()。设计一个机制并修改程序,以确保第二个()在第一个()之后执行,第三个()在第二个()之后执行 我的完整解决

假设我们有一个类:

公共类Foo{
public void first(){print(“first”);}
public void second(){print(“second”);}
public void third(){print(“third”);}
}
同一个Foo实例将传递给三个不同的线程。线程A将调用first(),线程B将调用second(),线程C将调用third()。设计一个机制并修改程序,以确保第二个()在第一个()之后执行,第三个()在第二个()之后执行

我的完整解决方案如下所示:

class-Foo{
int线程数;
公共食物({
这个.threadNumber=1;
}
synchronized public void first(Runnable printFirst)抛出InterruptedException{
while(threadNumber!=1){
等待();
}
//printFirst.run()输出“first”。请勿更改或删除此行。
printFirst.run();
threadNumber++;
notifyAll();
}
synchronized public void second(Runnable printSecond)引发InterruptedException{
while(threadNumber!=2){
等待();
}
//printSecond.run()输出“second”。请勿更改或删除此行。
printSecond.run();
threadNumber++;
notifyAll();
}
synchronized public void third(Runnable printThird)抛出InterruptedException{
while(threadNumber!=3){
等待();
}
//printThird.run()输出“third”。请勿更改或删除此行。
printThird.run();
threadNumber++;
notifyAll();
}
}
目前我不知道如何将Runnable对象传递给同步方法(这是任务条件之一):

公共类主{
公共静态void main(字符串[]args){
Foo-Foo=新的Foo();
CustomFirst CustomFirst=新CustomFirst();
CustomSecond CustomSecond=新的CustomSecond();
CustomThird CustomThird=新的CustomThird();
试一试{
foo.first(客户优先);
第三名(第三名);
第二名(第二名);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}

我想,这是一个来自中国的问题

目前我不知道如何将
Runnable
对象传递给同步方法(这是任务条件之一):

runnable
可以如下所示:

private static class PrintingRunnable implements Runnable {

    private final String string;

    public PrintingRunnable(String string) {
        this.string = string;
    }

    @Override
    public void run() {
        System.out.print(string);
    }
}
并通过为:

foo.first(new PrintingRunnable("first"));
foo.second(new PrintingRunnable("second"));
foo.third(new PrintingRunnable("third"));

请注意,不要求您提供自己的
Runnable
s,也不要求您创建
Thread
s来解决问题,只需实现
first
second
third
方法


在Java中,
Runnable
只不过是一些可以执行的操作。它可以打印一些东西,或者做其他任何事情

leetcode可能并不真正打印任何内容,而是使用不同的内容来测试提交。(对于试图解决问题的人来说,这并不重要)

但如果您想在本地执行此操作,可以使用上面的
PrintingRunnable

public static void main(String[] args) throws InterruptedException {
    Foo foo = new Foo();


    new Thread(() -> {
        try {
            foo.third(new PrintingRunnable("third"));
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }).start();
    new Thread(() -> {
        try {
            foo.first(new PrintingRunnable("first"));
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }).start();
    new Thread(() -> {
        try {
            foo.second(new PrintingRunnable("second"));
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }).start();
}

我想,这是一个来自中国的问题

目前我不知道如何将
Runnable
对象传递给同步方法(这是任务条件之一):

runnable
可以如下所示:

private static class PrintingRunnable implements Runnable {

    private final String string;

    public PrintingRunnable(String string) {
        this.string = string;
    }

    @Override
    public void run() {
        System.out.print(string);
    }
}
并通过为:

foo.first(new PrintingRunnable("first"));
foo.second(new PrintingRunnable("second"));
foo.third(new PrintingRunnable("third"));

请注意,不要求您提供自己的
Runnable
s,也不要求您创建
Thread
s来解决问题,只需实现
first
second
third
方法


在Java中,
Runnable
只不过是一些可以执行的操作。它可以打印一些东西,或者做其他任何事情

leetcode可能并不真正打印任何内容,而是使用不同的内容来测试提交。(对于试图解决问题的人来说,这并不重要)

但如果您想在本地执行此操作,可以使用上面的
PrintingRunnable

public static void main(String[] args) throws InterruptedException {
    Foo foo = new Foo();


    new Thread(() -> {
        try {
            foo.third(new PrintingRunnable("third"));
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }).start();
    new Thread(() -> {
        try {
            foo.first(new PrintingRunnable("first"));
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }).start();
    new Thread(() -> {
        try {
            foo.second(new PrintingRunnable("second"));
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }).start();
}

这种分步方案的ad-hock实现可以基于倒计时闩锁原语,如下所示:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class FooOrchestration {
    public static class Foo {
        public void first() { print("first"); }
        public void second() { print("second"); }
        public void third() { print("third"); }
    }

    static void print(String text) {
        System.out.println(text);
    }

    static class Step extends Thread {
        private final CountDownLatch starter = new CountDownLatch(1);
        private final List<Step> nextSteps = new ArrayList<>();
        private final Runnable action;

        Step(final Runnable action) {
            this.action = action;
        }

        @Override
        public void run() {
            try {
                starter.await(); // wait until someone kicks the starter with countDown()
                action.run();
                for (Step s : nextSteps) { // let's start the following steps
                    s.starter.countDown();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                for (Step s : nextSteps) { // let's propagate 
                    s.interrupt(); // the interruption
                }
            }
        }
    }

    public static void main(String[] args) throws Throwable {
        Foo foo = new Foo();

        Step firstStep = new Step(() -> foo.first());
        Step secondStep = new Step(() -> foo.second());
        Step thirdStep = new Step(() -> foo.third());

        firstStep.nextSteps.add(secondStep); // set sequence
        secondStep.nextSteps.add(thirdStep); // of execution

        thirdStep.start(); // order of start
        secondStep.start(); // doesn't
        firstStep.start(); // matter

        firstStep.starter.countDown(); // kick the starterof the first step
    }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.CountDownLatch;
公共类编排{
公共静态类Foo{
public void first(){print(“first”);}
public void second(){print(“second”);}
public void third(){print(“third”);}
}
静态无效打印(字符串文本){
System.out.println(文本);
}
静态类步骤扩展线程{
专用最终倒计时闩锁启动器=新倒计时闩锁(1);
private final List nextSteps=new ArrayList();
私人最终可运行行动;
步骤(最终可运行操作){
这个动作=动作;
}
@凌驾
公开募捐{
试一试{
starter.wait();//等待,直到有人用倒计时()踢启动机
action.run();
对于(步骤s:nextSteps){//让我们开始以下步骤
s、 starter.countDown();
}
}捕捉(中断异常e){
Thread.currentThread().interrupt();
对于(步骤s:nextSteps){//让我们传播
s、 interrupt();//中断
}
}
}
}
公共静态void main(字符串[]args)抛出可丢弃的{
Foo-Foo=新的Foo();
步骤firstStep=新步骤(()->foo.first());
第二步=新的步骤(()->foo.second());
第三步=新步骤(()->foo.third());
firstStep.nextSteps.add(secondStep);//设置序列
secondStep.nextSteps.add(thirdStep);//执行次数
第三步。开始();//开始顺序
secondStep.start();//没有
firstStep.start();//ma