为什么有多个线程进入同步块?

时间:2018-07-21 10:17:22

标签: java multithreading

我正在编写线程排序程序,该执行有两个方法“ prevMethod”和“ anotherMethod”在同一类中执行,并且在同一监视器共享对象“ lock1”中执行,那么为什么两个线程都在同一同步块中执行,却没有它违反了监视对象的目的。

class Ordering extends Thread {
    SharedObject obj = null;
    boolean flag = false;

    private AtomicInteger counter;

    Ordering(String name, SharedObject obj, AtomicInteger counter) {
        super(name);
        this.obj = obj;
        this.counter = counter;
    }

    public void run() {
        while (true) {
            prevMethod();
            System.out.println("New Method Started");
            anotherMethod();
        }
    }

    private void prevMethod() {
        synchronized (obj) {
            System.out.println(Thread.currentThread().getName() + " Section 1");
            while (!obj.flag) {
                try {
                    System.out.println(Thread.currentThread().getName() + " "
                            + counter.getAndIncrement());
                    obj.wait();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            obj.flag = true;
            obj.notify();
        }
    }

    private void anotherMethod() {
        synchronized (obj) {
            System.out.println(Thread.currentThread().getName() + " Section 2");

            while (obj.flag) {

                System.out.println(Thread.currentThread().getName() + " "
                        + counter.getAndIncrement());
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            obj.flag = false;
            obj.notify();
        }
    }
}

public class SequencialPrinting {

    public static void main(String... arg) {
        AtomicInteger counter = new AtomicInteger(3);
        SharedObject lock1 = new SharedObject();
        Thread t1 = new Thread(new Ordering("Thread 1", lock1, counter));
        Thread t2 = new Thread(new Ordering("Thread 2", lock1, counter));
        t1.start();
        t2.start();
    }
}

输出:

Thread-0 Section 1
Thread-0 3
Thread-1 Section 1
Thread-1 4

2 个答案:

答案 0 :(得分:0)

第一个线程调用prevMethod(),打印

线程0第1节 线程-0 3

并调用wait(),然后释放锁。

第二个线程调用prevMethod()

并打印

线程1第1节 线程1 4

两个线程正在进入同步块的位置。一次只有一个线程进入同步块

答案 1 :(得分:-2)

我从未见过像这样的代码...做新线程并将另一个新线程传递给构造函数... 您应该考虑以下两种情况之一:订购应仅在其主体中实现Runnable或2)仅创建一个新的订购(即一个线程)并启动它。

这就是代码中发生的事情: “线程-0”开始执行prevMethod,当它命中同步语句时便获得了监视器(现在拥有它)。 (无论如何,“ Thread-1”现在可能已停留在同一同步语句上),“ Thread-0”打印了“ Thread-0 Section 1”和“ Thread-0 3”。然后,它在监视器上执行等待。 等待放弃了监视器,因此现在“线程-0”已经放弃了监视器,正在等待通知。现在,“线程-0”不再是监视器的所有者,可以将其分配给停留在同步语句上的“线程-1”。现在“ Thread-1”通过同步语句(成为共享obj的所有者)并打印出enxt 2行,然后还放弃了监视器...