线程之间执行的顺序是什么? [英] What is the sequence of the execution between the threads?

查看:103
本文介绍了线程之间执行的顺序是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道线程之间执行的顺序,包括主线程。



也许举一个例子:

< pre lang =java> import java.util.concurrent.TimeUnit;

public class 资源1 {

public void f(){
// 其他操作不应该被锁定...
System.out.println(Thread.currentThread()。getName()
+ < span class =code-string> :f()中未同步);
synchronized this ){
for int i = 0 ; i< 5 ; i ++){
System.out.println(Thread.currentThread()。getName()
+ :在f()中同步);
尝试 {
TimeUnit.SECONDS.sleep( 3 );
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}

public void g(){
// 其他操作不应被锁定.. 。
System.out.println(Thread.currentThread()。getName()
+ :未在g()中同步);
synchronized this ){
for int i = 0 ; i< 5 ; i ++){
System.out.println(Thread.currentThread()。getName()
+ :在g()中同步);
尝试 {
TimeUnit.SECONDS.sleep( 3 );
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}

public void h(){
// 其他操作不应被锁定.. 。
System.out.println(Thread.currentThread()。getName()
+ :在h()中没有同步);
synchronized this ){
for int i = 0 ; i< 5 ; i ++){
System.out.println(Thread.currentThread()。getName()
+ :在h()中同步);
尝试 {
TimeUnit.SECONDS.sleep( 3 );
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}

public static void main( String [] args){
< span class =code-keyword> final Resource1 rs = new Resource1();

new 主题(){
public void run(){
rs.f();
}
} .start();

new 主题(){
public void run(){
rs.g();
}
} .start();

rs.h();
}
}



Q1:Thread-0,Thread-1和主线程的执行顺序如何?

(实际上,代码没有为线程分配名称。Thread-0和Thread-1是上面代码的打印输出结果,所以我只是将它们用作他们的当然,Thread-0是主线程创建的第一个线程。)



首先,主线程运行。然后它创建Thread-0并运行其.start()(即运行rs.f())。然后CPU专注于Thread-0。

直到代码TimeUnit.SECONDS.sleep(3); (遇到rs.f()),线程0睡眠并保持对象键,但是它将CPU的使用权传递回主线程。

和主线程(当前线程) )创建另一个线程,即thread-1,并调用Thread-1的run()。



现在,下一个执行的线程将是Thread-0或Thread-1 ?



Thread-0的原因:

As,有3个主题:主线程,Thread-0和Thread-1。执行顺序看起来如下:(顺序是从LHS到RHS,这是由于每个线程的创建顺序)



第1轮主要 Thread-0 Thread-1

第2轮主线程-0 线程-1

第3轮主线程-0 Thread-1



因此,下一个是线程0,因为主线程是前一个当前活动的线程。



Thread-1的原因:

由于主线程调用thread-1 .start() ,rs.g()实际上运行。





实际上,哪一个是正确答案?





Q2

让我们跳转到rs.g(),无论Q1的正确答案是什么。



Thread-1在同步块之前运行语句,然后运行synchronized块。当时,它发现实例对象键由其他人持有(它应该是Thread-0)。所以它暂停执行这里并将CPU的使用权传递给下一个。



但是下一个,主线程或线程0?< br $> b $ b



Q3

我在网上了解到当其中一个线程发布时同步块的对象键,没有规则可以预测下一次哪个线程可以获取密钥。

但是,只关注每次迭代CPU时间内线程的执行顺序。 br />


在上面的例子中,首先创建主线程,然后是Thread-0和Thread-1。

这是执行顺序每次迭代CPU时间的线程应该是

Main - >线程0 - >线程-1 ??



Q4

此外,如何让线程每次都做一些事情是活动线程并且无法获取synchronized块的实例对象键?

解决方案

线程之间的执行顺序,如果您没有使用线程添加特定约束同步原语是不确定的,并且在实践中,在应用程序的不同执行中确实有所不同。对软件开发中的任何特定顺序使用任何假设都会使应用程序无效(除非它是故意设计用于证明执行顺序随机性的影响)。这是一个称为对执行顺序的不正确依赖的已知问题,或更广泛的术语,竞争条件http://en.wikipedia.org/wiki/Race_condition [ ^ ]。



-SA


I want to know the sequence of the execution between the threads including the main thread.

Maybe take an example:

import java.util.concurrent.TimeUnit;

public class Resource1 {

    public void f() {
        // other operations should not be locked... 
        System.out.println(Thread.currentThread().getName()
                + ":not synchronized in f()");
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()
                        + ":synchronized in f()");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void g() {
        // other operations should not be locked... 
        System.out.println(Thread.currentThread().getName()
                + ":not synchronized in g()");
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()
                        + ":synchronized in g()");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void h() {
        // other operations should not be locked... 
        System.out.println(Thread.currentThread().getName()
                + ":not synchronized in h()");
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()
                        + ":synchronized in h()");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        final Resource1 rs = new Resource1();

        new Thread() {
            public void run() {
                rs.f();
            }
        }.start();

        new Thread() {
            public void run() {
                rs.g();
            }
        }.start();

        rs.h();
    }
}


Q1: How is the execution order of Thread-0 , Thread-1 and main thread ?
(Actually, the code does not assign the names for the threads. "Thread-0" and "Thread-1" are the printout result of the code above, so I just use them as their names. Of course, "Thread-0" is the first created thread by main thread.)

Firstly, main thread runs. Then it creates Thread-0 and run its .start() (ie running rs.f() ). Then CPU focus on the Thread-0.
Until the code "TimeUnit.SECONDS.sleep(3);" (inside rs.f() ) is encountered, the thread-0 sleeps and keeps the object key, but it pass the right of use of CPU back to main thread.
And main thread (current thread) creates another thread ie thread-1 and calls the run() of Thread-1.

Now, the next executing thread would be Thread-0 or Thread-1?

The reason for Thread-0:
As, there are 3 threads: main thread, Thread-0 and Thread-1. The execution order looks alike as below: (the order is from LHS to RHS, it is due to the creation order of each thread)

Round 1 Main Thread-0 Thread-1
Round 2 Main Thread-0 Thread-1
Round 3 Main Thread-0 Thread-1

So, the next one is thread-0 since Main thread is the immediate previous currently active thread.

The reason for Thread-1:
Since main thread calls thread-1 .start(), the rs.g() runs actually.


In fact, which one is the right answer?


Q2
Let's jump to rs.g() , no matter what the right answer of Q1 is.

Thread-1 runs the statement right before the synchronized block, then runs the synchronized block. At the time, it finds the instance object key is held by someone else(it should be Thread-0). So it pauses the execution here and pass the right of use of CPU to the next one.

But which is the next one, Main thread or thread-0?


Q3
I learnt online that when one of the threads releases the object key of the synchronized block, there is no rule to predict which thread could get the key next time.
However, just focus on the execution order of the threads in each iteration of the CPU time.

In the above example, main thread is created first, followed by Thread-0 and Thread-1.
Is that the execution order of the threads in each iteration of the CPU time should be
Main --> Thread-0 --> Thread-1 ??

Q4
besides, how to ask the thread to do something each time it is being active thread and fails to get the instance object key of the synchronized block?

解决方案

The order of execution between threads, if you are not adding specific constraints using thread synchronization primitives, is uncertain and, in practice, really varies in different executions of the application. The use of any assumptions on any certain order in software development makes the application invalid (unless it is designed intentionally to demonstrate the effects of randomness of the order of execution). This is a know problems called "incorrect dependency on the order of execution", or, more widespread term, "race condition": http://en.wikipedia.org/wiki/Race_condition[^].

—SA


这篇关于线程之间执行的顺序是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆