0

拜托,我对以下场景的同步块和同步方法有疑问:

第1部分 - - - - - - - :

Class table
{
    Synchronized(this)
    {
        ……………………
    }
}

在这里,我们锁定了表类的对象。--------------------------------------------------……</p>

第2部分:

Class table
{
    Customer cust=new Customer();
    Synchronized(cust)
    {
        ……………………
    }
}

在这里,我们锁定了 customer.ie on cust 在第 1 部分中,我们锁定了?- 表类的对象。我们锁定了表类,因为表类的对象可能会尝试
同时从不同的地方访问同步块。为了防止它,我们在第 1 部分中锁定了表类
的对象。现在来到第 2 部分:?- 这里我们锁定了客户类的对象 ---------------------------------- ----…</p>

我的疑惑:

  1. 为什么我们要锁定表类中的对象而不是第 2 部分中的表类?

  2. 如果我们在第 2 部分中没有锁定 cust,那么我们可以使用表类访问同步块。如果我们锁定 cust,那么我们还需要表类的对象来访问同步块。表类的对象只需要访问同步块。由于同步,我们阻止了表类的对象
    同时从不同的线程访问同步块。那么为什么要在表类中锁定表类以外的对象呢?

  3. 客户类的对象会尝试从
    不同的地方同时访问同步块吗?

  4. 在第 2 部分中,我们锁定了表类以外的对象。在什么情况下,在表类对象上锁定表类对象是在第 2
    部分锁定客户类对象的好处?

  5. 什么需要锁定客户类的对象,即表类以外的对象?

  6. 如果我们没有在part2中锁定客户类的对象,会发生什么损害?

拜托,我是 Java 线程的新手,一段时间以来我一直在努力解决这些问题。任何明确的解释都会有很大帮助。谢谢

4

2 回答 2

1

您应该检查的第一件事是:使用不同类型的“同步”关键字保护什么样的 DATA 字段。

静态变量/方法是类级别的对象,所有其他变量/方法是实例级别的。

类级锁是使类的所有对象等待直到相应的锁未被释放的锁。

例如

Class A{
static synchronized void foo(){}
}

这里方法 foo 是同步的,因此类的所有对象上的所有线程都将等待,直到当前运行 foo 方法的对象完成其执行。

类似地,实例级锁使使用该类的实例启动的所有线程等待直到锁未被释放。

例如

Class A{
synchronized void bar(){}
}

这里从当前正在执行 bar 方法的对象启动的所有线程都将等待,直到当前线程完成其执行。请注意,其他对象的其他线程可以执行 bar 方法,而另一个对象的线程正在执行 bar 方法。

换句话说,一个线程在持有适当的对象锁之前不能进入一个同步的代码块。

对于instance methods,这是一个实例的锁。

因为static methods这是 Class 对象锁。

于 2012-12-13T08:28:32.543 回答
0

看来您分析了一些现有代码并试图理解为什么会有同步。

第 1 部分和第 2 部分代码是否在同一个函数中?

在第二部分中,同步没有意义。创建客户对象然后进行同步无效。第二个线程将创建一个新的客户对象并锁定该对象。

如果您需要更改现有代码,您可以编写一个测试用例并跨越多个线程并删除同步以查看是否可以强制执行多线程问题。

于 2012-12-13T08:52:25.670 回答