5

假设我们有这种情况:

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();
//...

每种类型的线程在运行时都会打印出自己独特的语句。

我注意到每次执行程序时,输出总是不同的。例如,来自 ChilThread1 t1 的语句将在输出中间打印而不是开始(因为 t1 首先开始)或者语句“所有线程都准备好”将在线程执行中间弹出(例如:ChilThread2 是'所有线程都准备好了' 跑步 )

所以我试图找到答案,我找到了这个网站:http ://www.avajava.com/tutorials/lessons/how-do-i-use-threads-join-method.html 该网站基本上说没有保证订单使用 start() 时的执行时间

那么我是否可以假设这种奇怪的打印顺序是因为 start() 不保证执行顺序?这个原因是否也适用于“所有线程都准备好”的问题?

4

4 回答 4

5

线程的全部意义在于它们可以同时执行。如果您想确保完成事情的特定顺序,您要么必须放弃使用线程,要么使用显式同步。

那么我是否可以假设这种奇怪的打印顺序是因为 start() 不保证执行顺序?

这是正确的。当你start是一个线程时,主线程和新创建的线程之间基本上存在竞争条件。这意味着对于两个线程之间发生的事情的相对顺序无话可说。如果要确保特定排序,请使用同步。

于 2012-11-05T08:12:37.773 回答
2

当您启动一个线程时,启动的线程将与所有已经运行的线程并行运行。线程调度程序在可用处理器上分派各种线程,每个线程轮流获得一些处理器时间。但是处理器,分配给每个线程的顺序和时间取决于操作系统线程调度程序,您绝对无法保证。

于 2012-11-05T08:12:20.030 回答
2

保持线程执行顺序的简单方法是使用信号量

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

}

}

于 2015-12-16T04:43:30.330 回答
1

那么我是否可以假设这种奇怪的打印顺序是因为 start() 不保证执行顺序?

是的。你说的对。

这个原因是否也适用于“所有线程都准备好”的问题?

是的。又对了。你SOP是由主线程运行的。所以,有可能在有机会执行它t1之前打印一些东西。mainSOP

于 2012-11-05T08:12:00.740 回答