简体   繁体   English

多线程执行顺序

[英]Execution order of multiple threads

Let's say we have this scenario:假设我们有这样的场景:

class Stack{

public void main{

ChildThread1 t1 = new ChildThread1;
ChildThread1 t2 = new ChildThread1;
ChildThread1 t3 = new ChildThread1;

//then we make some ChildThread2 objects and some ChildThread3 objects

ChildThread2 s1 = new ChildThread2;
//...

ChildThread3 v1 = new ChildThread3;
//...

//now we let all threads start in mix order
t1.start();
v1.start();
//...

SOP("All threads are ready");

//then we let them run with join()
t1.join();
t2.join();
t3.join();

s1.join();
//...

v1.join();
//...

Each type of thread prints its own unique statement when it is running.每种类型的线程在运行时都会打印自己唯一的语句。

I noticed that every time I execute the program, the output is always different.我注意到每次执行程序时,输出总是不同的。 For example, a statement from ChilThread1 t1 will print in the middle of output instead of beginning (since t1 starts first) or the statement "all threads are ready" will pop in middle of thread execution (Example: ChildThread2 is 'all threads are ready' running )例如,来自 ChilThread1 t1 的语句将在输出的中间打印而不是开始(因为 t1 首先启动)或者语句“所有线程都准备好了”将在线程执行中间弹出(例如:ChildThread2 是“所有线程都准备好了” ' 跑步 )

So I tried to find an answer and I found this site: http://www.avajava.com/tutorials/lessons/how-do-i-use-threads-join-method.html The site basically says there's no guarantee order of execution when you use start()所以我试图找到一个答案,我找到了这个网站: http : //www.avajava.com/tutorials/lessons/how-do-i-use-threads-join-method.html该网站基本上说没有保证订单使用 start() 时的执行

So am I right to assume that this weird order of prints is because start() does not guarantee order of execution?那么我是否正确地假设这种奇怪的打印顺序是因为 start() 不保证执行顺序? Will this reason also apply to 'all threads are ready' problem?这个原因是否也适用于“所有线程都准备就绪”的问题?

The whole point of threads is that they can be executed concurrently.线程的全部意义在于它们可以并发执行。 If you want to ensure specific order in which things are done, you either have to move away from using threads, or use explicit synchronization.如果您想确保完成事情的特定顺序,您要么必须放弃使用线程,要么使用显式同步。

So am I right to assume that this weird order of prints is because start() does not guarantee order of execution?那么我是否正确地假设这种奇怪的打印顺序是因为 start() 不保证执行顺序?

That's right.这是正确的。 When you start a thread, there's basically a race condition between the main thread and the newly created thread.当您start一个线程时,主线程和新创建的线程之间基本上存在竞争条件。 This means that nothing can be said about the relative order in which things happen between the two threads.这意味着无法说明两个线程之间发生的相对顺序。 If you want to ensure specific ordering, use synchronization.如果要确保特定顺序,请使用同步。

Easy way to maintain ordering in Thread Execution is to use Semaphore在线程执行中维护排序的简单方法是使用信号量

public class Semaphore {

int value;

public Semaphore(int intialValue) {
    this.value = intialValue;
}

public synchronized void p() {
    while (value <= 0) {
        try {
            this.wait();
        } catch (InterruptedException e) {
        }

    }
    value = value - 1;
}

public synchronized void v() {
    value = value + 1;
    this.notify();
}

} }

public class ThreadSync {

static Semaphore semaphore = new Semaphore(0);

public static void main(String[] args) {
    // t1 should be executed before t2
    Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {
            semaphore.p();
            System.out.println("executing " + Thread.currentThread().getName());
        }
    });
    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() {
            System.out.println("executing " + Thread.currentThread().getName());
            semaphore.v();
        }
    });

    t1.setName("Thread 1");
    t2.setName("Thread 2");
    t2.start();
    t1.start();

}

} }

So am I right to assume that this weird order of prints is because start() does not guarantee order of execution?那么我是否正确地假设这种奇怪的打印顺序是因为 start() 不保证执行顺序?

Yes.是的。 You are right.你是对的。

Will this reason also apply to 'all threads are ready' problem?这个原因是否也适用于“所有线程都准备就绪”的问题?

Yes.是的。 Right again.又对了。 Your SOP is run by main thread.您的SOP由主线程运行。 So, it's possible that t1 can print something before main gets chance to execute it's SOP .因此, t1可能在main有机会执行它的SOP之前打印一些东西。

When you start a thread, the started thread runs in parallel of all the already running threads.当您启动一个线程时,启动的线程与所有已运行的线程并行运行。 The thread scheduler dispatches the various threads on the available processors, and each thread gets some processor time, each in his turn.线程调度程序在可用处理器上调度各种线程,每个线程轮流获得一些处理器时间。 But the processor, the order and the time assigned to each thread is up to the OS thread scheduler, and you have absolutely no guarantee.但是处理器,分配给每个线程的顺序和时间取决于操作系统线程调度程序,您绝对无法保证。

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

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