繁体   English   中英

多线程无法执行 java 中的非同步代码

[英]Multiple thread failed to execute the nonsynchronized code in java

如果 Thread1 获得锁并开始执行同步块,同时,Thread2 可以自由执行代码的非同步部分,即IntStream.range(0, 5).forEach(x -> System.out.println("thread Unsafe Zone,"+name))

出乎意料的是,以下是我运行代码时实际发生的情况。

解释-

假设thread1(或thread2)获得锁并执行同步块,然后thread2(或thread1)获得thread1(或thread2)释放的锁并执行同步块。当两个线程都执行完同步块后,则两者线程并行开始执行非同步部分。 我多次运行代码希望获得所需的 output 但未能成功。

演示 class

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

        Display d=new Display("AnyName");
        Thread1 t1=new Thread1(d);
        Thread2 t2=new Thread2(d);
        t1.start();
        t2.start();
    }
}

螺纹1 class

public class Thread1 extends Thread {
    Display d;
    Thread1(Display d) {
        this.d = d;
    }
    @Override
    public void run() {
       d.getname("Thread 1");
    }
}

螺纹2 class

public class Thread2 extends Thread {
    Display d;

    Thread2(Display d) {
        this.d = d;
    }

    @Override
    public void run() {
            d.getname("Thread 2");
    }
}

显示器 class

public class Display {
    String name;

    public Display(String name) {
        this.name = name;
    }

    public void getname(String name)  {
        synchronized (this) {
            IntStream.range(0, 5).forEach((idx) -> {
                System.out.println(name);
            });
            this.name=name;
        }

        IntStream.range(0, 5).forEach(x -> System.out.println("thread Unsafe Zone,"+name));// this line
//get executed only after the synchronized method completed by both thread

    }
}

Output:

Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2

如果 Thread1 获得锁并开始执行同步块,在同一时间,Thread2 可以自由执行代码的非同步部分:不完全是。

在执行顺序中,非同步块跟在同步块之后。 因此,您将永远不会看到任何线程在同步块之前执行非同步块。

你能期待的最好的东西是

Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2

其中线程 2 进入同步块,而线程 1 在非同步块中运行。

您可以通过调用Thread.yield();更改Display.getname()方法来增加出现这种结果的机会; 在同步块之后并通过执行更多System.out.println()调用:

public void getname(String name)  {
    synchronized (this) {
        IntStream.range(0, 5).forEach((idx) -> {
            System.out.println(name);
        });
        this.name=name;
    }
    Thread.yield();

    IntStream.range(0, 20).forEach(x -> System.out.println("thread Unsafe Zone,"+name));

}

暂无
暂无

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

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