在Java中执行两个同步块

Mob*_*eam 4 java multithreading

为什么Java中的两个不同线程无法同时执行两个同步块.

编辑

public class JavaApplication4 {

    public static void main(String[] args) {
        new JavaApplication4();
    }

    public JavaApplication4() {
        Thread t1 = new Thread() {

            @Override
            public void run() {
                if (Thread.currentThread().getName().equals("Thread-1")) {
                    test(Thread.currentThread().getName());
                } else {
                    test1(Thread.currentThread().getName());
                }
            }
        };
        Thread t2 = new Thread(t1);
        t2.start();
        t1.start();

    }

    public synchronized void test(String msg) {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
            }
            System.out.println(msg);
        }
    }

    public synchronized void test1(String msg) {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
            }
            System.out.println(msg + " from test1");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*nik 11

你的陈述是错误的.只要不争用相同的锁,任何数量的同步块都可以并行执行.

但是如果你的问题是关于争用同一个锁的块,那么问"为什么会这样"是错误的,因为这是整个概念的目的.程序员需要一个互斥机制,他们从Java中获取它synchronized.

最后,您可能会问"为什么我们需要相互排除代码段并行执行".答案就是有许多数据结构只有在以某种方式组织时才有意义,当线程更新结构时,它必然是逐个部分地进行,因此结构处于"损坏"状态而它正在进行更新.如果另一个线程在那一点出现并试图读取结构,或者更糟糕的是,自己更新它,整个事情就会崩溃.

编辑

我看到了你的例子和你的评论,现在很明显是什么让你烦恼:synchronized方法修饰语的语义.这意味着该方法将争夺锁定this的监视器.synchronized同一对象的所有方法都将争用同一个锁.


Kam*_*mal 5

这就是同步的整个概念,如果您要锁定一个对象(或类),则其他线程都无法访问任何同步块。

例子

Class A{

public void method1()
{
 synchronized(this)//Block 1 taking lock on Object
 {
  //do something
 }
}

public void method2()
{
 synchronized(this)//Block 2 taking lock on Object
 {
  //do something
 }
}
}
Run Code Online (Sandbox Code Playgroud)

如果一个对象的一个​​线程进入任何同步块,则同一对象的所有其他线程将必须等待该线程从同步块中出来才能进入任何同步块。如果有 N 个这样的块,则对象的一个​​线程一次只能访问一个块。请注意我对同一对象的线程的强调。如果我们处理来自不同对象的线程,这个概念将不适用。

我还要补充一点,如果您锁定class,则上述概念将扩展到该类的任何对象。因此,如果不是说synchronized(this),我会使用synchronized(A.class),代码将指示 JVM,无论线程属于哪个对象,都让它等待其他线程完成同步块执行。

编辑:请理解,当您锁定(通过使用同步关键字)时,您不仅仅是锁定一个块。您正在锁定该对象。这意味着您告诉 JVM“嘿,这个线程正在执行一些可能会更改对象(或类)状态的关键工作,因此不要让任何其他线程执行任何其他关键工作”。这里的关键工作指的是同步块中锁定特定对象(或类)的所有代码,而不仅仅是一个同步块中的代码。