2014-10-02 45 views
2

我熟悉基本的Java线程机制,但是,对某个特定情况感到困惑。以下是示例代码。Java - 同步块上的字节[]

static byte[] syncBuf; 

// synchronized block of code 
synchronized(syncBuf) { 
    // Call non-synchronized method 
    methodA(syncBuf); 
} 

我的问题是如果多个线程执行上面的代码,将下一个线程块,直到了methodA()执行完毕,因为我们正在持有锁syncBuf其通过引用传递。

编辑:

如果我更改上面的代码与下面的情况:

static byte[] syncBuf; 

// synchronized block of code 
synchronized(syncBuf) { 
    // Call non-synchronized method in a new thread 
    new Thread(new Runnable() { 
    @Override 
    public void run() { 
     methodA(syncBuf); 
    }}).start(); 
} 

请问上述解释仍持有?下一个线程会阻塞,直到methodA() - 线程执行完毕吗?

回答

3

你的解释是(大部分)是正确的。调用该代码的任何其他线程都会阻塞,直到线程退出同步块(稍后methodA返回)。

在Java中,数组也是可以同步的对象。

您可以随时实验和尝试,验证,无论是通过使用调试器或明智地使用Thread.sleep代码的功能,看看其他线程可以得到。

你的编辑是一个完全不同的情况下,虽然 - 在这里,您的主线程会锁定syncBuf,启动一个线程,然后释放该锁。该线程不会获取锁(在run()内),因此对methodA(syncBuf)的调用不会获取任何锁或进行任何阻塞。这与在这里匿名Runnable实例在其他地方定义的相同(例如在它自己的类中)。

+0

是的,我试过这么做。但是,在进入同步代码块之前,syncBuf既不会被搞乱,也不会被调用线程长时间阻塞。不知道如何验证它。 – pree 2014-10-03 00:03:00

+0

以上评论是针对我编辑的问题。我可以在第一种情况下验证它。调用线程在第一种情况下会被阻塞。 – pree 2014-10-03 00:13:03

1

关于你的编辑

请问上述解释仍持有?下一个线程会阻止 ,直到methodA() - 线程执行完毕吗?

您创建一个新的线程调用其异步methodA。从当前线程的角度来看,即。在syncBuf上拥有锁的那个,你调用了Thread#start()方法,该方法立即返回并退出​​块,释放该锁。

0

Chris和Sotirios Delimanolis的上述答案都是正确的。我只是将其中的一个标记为涵盖两种情况的答案。