4

给定三个线程 1-3 打印一个字母 AC,我如何保证输出顺序?

我希望线程的输出是“ABCABCABC”

4

9 回答 9

4

线程独立运行,因此除非您执行特殊的工作来同步线程,否则您永远不会得到这样的输出。预计独立运行的 3 个线程将打印“随机”输出,因为由操作系统来安排线程。

于 2013-04-14T09:21:01.063 回答
4

这可能不是线程应该做的,但可以通过简单地使用 join 来实现(它要求启动ING线程等待启动ED线程的完成。

class A implements Runnable {

@Override
public void run() {
    try {
        Thread.sleep(12);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("ClassA : A");
}

}

class B implements Runnable {

@Override
public void run() {
    try {
        Thread.sleep(12);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("ClassB : B");
}

}

class C implements Runnable {

@Override
public void run() {
    try {
        Thread.sleep(12);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("ClassC : C");
}

}

public class OrderedThreadApp {
public static void main(String[] args) {

    Thread a = new Thread(new A());
    Thread b = new Thread(new B());
    Thread c = new Thread(new C());

    a.start();
    try {
        a.join();
        b.start();
        b.join();
        c.start();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}
于 2015-09-20T15:00:37.267 回答
1

我的解决方案在这里:https ://gist.github.com/sinujohn/5fa717dfff680634c6b0c2a7eca108ac可以修改来实现这一点。这个想法是创建一个保存状态的对象并在所有线程之间共享该对象。只有一个同步块可以访问共享状态对象。

public class Main {

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

        final Thread t1 = new Thread(new MyRunnable(10, 'A', state));
        final Thread t2 = new Thread(new MyRunnable(10, 'B', state));
        final Thread t3 = new Thread(new MyRunnable(10, 'C', state));
        t1.start();
        t2.start();
        t3.start();
    }
}

class MyState {
    private char state = 'A';

    public char getState() {
        return state;
    }

    public void incrState() {
        switch(state) {
        case 'A':
            state = 'B';
            return;
        case 'B':
            state = 'C';
            return;
        default:
            state = 'A';
        }
    }
}

class MyRunnable implements Runnable {

    private final int max;
    private final char value;
    private final MyState state;

    MyRunnable(int max, char value, MyState state) {
        this.max = max;
        this.value = value;
        this.state = state;
    }

    @Override
    public void run() {
        int count = 0;
        while(count < max) {
            synchronized (this.state) {
                if (this.state.getState() == this.value) {
                    System.out.print(value);
                    count++;
                    this.state.incrState();
                }
            }
        }
    }
}
于 2018-08-10T18:20:40.203 回答
0

检查CyclicBarrier,这可能会对您有所帮助。

于 2013-04-14T09:51:34.427 回答
0

您可以使用等待和通知进行线程间通信。我在这里使用 turn int 变量在线程之间发出信号。

public class ThreadInterleaving{
    public static void main(String[] args){

    MyThread h = new MyThread();

    Thread t1 = new Thread(h);
    Thread t2 = new Thread(h);
    Thread t3 = new Thread(h);

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

    }
}

class MyThread implements Runnable{
    public static int turn;

    @Override
    public void run(){
        for(int i =0;i<3;i++){
            synchronized(this){
                if(turn == 0){
                    System.out.println("Thread1");
                    turn =1 ;
                    notify();
                }else{
                    try{
                        wait();
                    }catch(InterruptedException ie){

                    }
                }

                if(turn == 1){
                    System.out.println("Thread2");
                    turn = 2;
                    notify();
                }else{
                    try{
                        wait();
                    }catch(InterruptedException ie){

                    }
                }

                if(turn == 2){
                    System.out.println("Thread3");
                    System.out.println("*********");
                    turn = 0;
                    notify();
                }else{
                    try{
                        wait();
                    }catch(InterruptedException ie){        

                    }
                }
            }
        }
    }
}

/*Output
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
Thread1
Thread2
Thread3
*********
*/
于 2015-11-11T17:13:06.510 回答
0
public class RunningThreadSequentially {
    //Runnable task for each thread
    private static class Task implements Runnable {
        public static int counter=0;

        @Override
        public void run() {
            try {
                synchronized(this) {
                    Thread.sleep(500);
                    System.out.println(Thread.currentThread().getName() + " is completed--" + counter ++);             
                }
            } catch (Exception ex) {
            } 
        }
    }

    public static void main(String args[]) throws InterruptedException {
        while(true) {
            Thread t1 = new Thread(new Task(), "Thread 1");
            Thread t2 = new Thread(new Task(), "Thread 2");
            Thread t3 = new Thread(new Task(), "Thread 3");
            Thread t4 = new Thread(new Task(), "Thread 4");
            Thread t5 = new Thread(new Task(), "Thread 5");
            Thread t6 = new Thread(new Task(), "Thread 6");

            t1.start();
            t1.join();
            t2.start();
            t2.join();
            t3.start(); 
            t3.join(); 
            t4.start(); 
            t4.join(); 
            t5.start();
            t5.join(); 
            t6.start(); 
            t6.join();
        }
    }
}
于 2020-02-15T14:02:50.677 回答
0

CountDownLatch您可以通过组合和来实现这一点CyclicBarrier。这是示例代码:

    package org.orange.didxga;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

public class ThreadExecutionOrder {

    private CountDownLatch countDownLatch = new CountDownLatch(2);
    private CountDownLatch countDownLatch1 = new CountDownLatch(1);
    private CyclicBarrier barrier;
    private final Object monitor = new Object();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ThreadExecutionOrder().test();
    }

    public void test() {
        Runnable t1 = new Runnable() {

            @Override
            public void run() {
                System.out.print("A");
                countDownLatch1.countDown();
                countDownLatch.countDown();
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }

        };
        Runnable t2 = new Runnable() {

            @Override
            public void run() {
                try {
                    countDownLatch1.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print("B");
                countDownLatch.countDown();
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }

        };
        Runnable t3 = new Runnable() {

            @Override
            public void run() {
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print("C");
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }

        };
        for(int i=0; i<3; i++) {
            barrier = new CyclicBarrier(3, new Runnable()  {
                @Override
                public void run() {
                    synchronized (monitor) {
                        countDownLatch = new CountDownLatch(2);
                        countDownLatch1 = new CountDownLatch(1);
                        monitor.notify();
                    }
                }

            });
            new Thread(t1).start();
            new Thread(t2).start();
            new Thread(t3).start();
            synchronized (monitor) {
                try {
                    monitor.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
于 2015-08-23T07:15:54.443 回答
-1
public class ThreadOrderTest {

int status = 1;

public static void main(String[] args) {
    ThreadOrderTest threadOrderTest = new ThreadOrderTest();
    A a = new A(threadOrderTest);
    B b = new B(threadOrderTest);
    C c = new C(threadOrderTest);
    a.start();
    b.start();
    c.start();
}
}

class A extends Thread {

ThreadOrderTest threadOrderTest;

A(ThreadOrderTest threadOrderTest) {
    this.threadOrderTest = threadOrderTest;
}

@Override
public void run() {
    try {
        synchronized (threadOrderTest) {
            for (int i = 0; i < 10; i++) {
                while (threadOrderTest.status != 1) {
                    threadOrderTest.wait();
                }
                System.out.print("A ");
                threadOrderTest.status = 2;
                threadOrderTest.notifyAll();
            }
        }
    } catch (Exception e) {
        System.out.println("Exception 1 :" + e.getMessage());
    }
}
}

class B extends Thread {

ThreadOrderTest threadOrderTest;

B(ThreadOrderTest threadOrderTest) {
    this.threadOrderTest = threadOrderTest;
}

@Override
public void run() {
    try {
        synchronized (threadOrderTest) {
            for (int i = 0; i < 10; i++) {
                while (threadOrderTest.status != 2) {
                    threadOrderTest.wait();
                }
                System.out.print("B ");
                threadOrderTest.status = 3;
                threadOrderTest.notifyAll();
            }
        }
    } catch (Exception e) {
        System.out.println("Exception 2 :" + e.getMessage());
    }
}
}

class C extends Thread {

ThreadOrderTest threadOrderTest;

C(ThreadOrderTest threadOrderTest) {
    this.threadOrderTest = threadOrderTest;
}

@Override
public void run() {
    try {
        synchronized (threadOrderTest) {
            for (int i = 0; i < 10; i++) {
                while (threadOrderTest.status != 3) {
                    threadOrderTest.wait();
                }
                System.out.println("C ");
                threadOrderTest.status = 1;
                threadOrderTest.notifyAll();
            }
        }
    } catch (Exception e) {
        System.out.println("Exception 3 :" + e.getMessage());
    }
}
}
于 2014-03-18T21:31:41.923 回答
-2

执行服务

一个 Executor,它提供了管理终止的方法和可以生成 Future 以跟踪一个或多个异步任务的进度的方法。

可以关闭 ExecutorService,这将导致它拒绝新任务。提供了两种不同的方法来关闭 ExecutorService。shutdown() 方法将允许先前提交的任务在终止之前执行,而 shutdownNow() 方法阻止等待的任务启动并尝试停止当前正在执行的任务。终止后,执行者没有正在执行的任务,没有等待执行的任务,也没有新的任务可以提交。应关闭未使用的 ExecutorService 以允许回收其资源。

方法 submit 通过创建和返回可用于取消执行和/或等待完成的 Future 扩展了基本方法 Executor.execute(java.lang.Runnable)。方法 invokeAny 和 invokeAll 执行最常用的批量执行形式,执行一组任务,然后等待至少一个或全部完成。(类 ExecutorCompletionService 可用于编写这些方法的自定义变体。)

Executors 类为此包中提供的执行器服务提供工厂方法。

于 2013-04-14T09:24:40.517 回答