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