我有点困惑。请看看下面的代码。
public class ThreadDemo {
//non-static synchronized method
synchronized void a(){
actBusy();
}
//static synchronized method
static synchronized void b(){
actBusy();
}
//static method
static void actBusy(){
try{
Thread.sleep(1000);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
final ThreadDemo x = new ThreadDemo();
final ThreadDemo y = new ThreadDemo();
Runnable runnable = new Runnable() {
public void run() {
int option = (int) (Math.random() * 4);
switch (option){
case 0: x.a();
break;
case 1: x.b();
break;
case 2: y.b();
break;
case 3: y.b();
break;
}
}
} ;
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
t1.start();
t2.start();
}
}
我确信调用此序列是可能的。
x.a() //in Thread-1
y.b() //in Thread-2
虽然我仍然有一个小小的困惑,但我们可以很容易地看到x.a()
也调用actBusy()
方法,这是一个静态方法。方法 b()
是调用非同步静态方法的静态同步方法。当 thread-2 获得类级锁时,为什么从 Thread-1 调用 actBusy()
没有被阻止?
我只是在逻辑上感到困惑,如果一个线程获得类级锁定,则该类其他非同步静态方法保持打开状态,以便从其他方法(实例方法)调用。为什么?
actBusy()
本身不是同步的,但调用方方法是同步的。
因此,线程1在获取< code>this对象上的锁时不会阻塞,并且没有其他线程持有< code>this上的锁,因此它能够毫无问题地调用它。
这是因为<code>非静态同步
x.a()
在当前实例(即 x
)上抓取一个锁,在当前线程释放锁之前,没有其他线程能够输入 x
的方法 a()。
线程1 -
线程2 -
编辑:
Class Object != Instance
所以根据JMM,它们是不同的对象,两个线程不会相互干扰。所以它允许您调用它。
编辑2:
为什么它允许调用其他静态方法?背后有什么逻辑吗?
假设:
public static synchronized int statefulMethod(){
//this should be protected
}
public static int nonStatefulMethod(){
//Just returns a static value such as 5
//so this is thread safe as it does not have any state
}
public static synchronized int otherStatefulMethod(){
//this should also be thread safe
}
因此,如果线程 1 处于方法 statefulMethod()
中,则它具有一些共享状态需要保护,因此它使用类级锁。现在线程2调用nonStatefulMethod(),
那么它不应该在逻辑上阻塞,因为该方法是线程安全的,在这里创建该线程块是没有意义的。
现在,如果线程3在线程1持有类锁时调用therStatefulMethod()
,那么线程3将不得不等待,因为该方法也是静态同步的
。
static synchronized
方法在类对象上有一个锁,而非静态synchronize
method在实例对象上有锁(this
)-因此两个方法可以同时调用,一个线程将运行1,而另一个线程运行第二个线程。
但是,请注意,在您的代码中没有可用的竞争条件,因为竞争条件需要写操作,而这在这些方法中不存在。
那么为什么线程-1中的actBusy()
调用没有被阻止?
因为您的actBusy
方法未同步。即使获得了类级锁,也可以调用非同步静态方法。
将方法标记为< code>synchronized的目的是启用锁。只有声明为synchronized的方法才受这些锁的约束。因此,如果您获取了一个锁(假设是类级别的锁),那么任何< code >非同步方法都会像以前一样工作,并且不知道锁被获取了。这允许您决定哪些方法需要被阻止,哪些不需要。
本文向大家介绍java synchronized同步静态方法和同步非静态方法的异同,包括了java synchronized同步静态方法和同步非静态方法的异同的使用技巧和注意事项,需要的朋友参考一下 java synchronized 详解 synchronized关键字有两种用法,一种是只用于方法的定义中,另外一种是synchronized块,我们不仅可以使用synchronized来同步一个对
问题内容: 任何人都可以解释以下语句吗……“静态同步方法和非静态同步方法不会互相阻塞-它们可以同时运行” 问题答案: 锁定对象在静态方法和非静态方法上有所不同。静态方法将Class对象用作锁(锁obj:),而非静态方法将实例对象用作锁,此时方法的调用已绑定到该对象(锁obj:)。
我正在编写的代码需要在几个静态方法之间进行一些同步。我的目标是阻止执行这些方法中的任何一个,如果其中一个执行。例如: 现在让我们假设下面的代码是从代码中的某个地方执行的: 我的问题是: > 它实际上是同步的吗?methodA和methodB不会同时运行吗? 如果是,methodA调用methodB会不会造成死锁?
问题内容: 在Java中同步静态方法和非静态方法有什么区别?有人可以举例说明吗?在同步方法和同步代码块方面也有什么区别吗? 问题答案: 我将尝试添加示例以使这一点更加清楚。 如前所述,Java中的同步是Monitor概念的实现。当您将代码块标记为同步时,可以使用一个对象作为参数。当执行线程进入这样的代码块时,它必须首先等待,直到同一对象上的同步块中没有其他执行线程。 在上面的示例中,一个正在运行的
主要内容:1 什么是Java静态同步方法,2 没有静态同步方法的问题,3 静态同步方法的例子1,4 静态同步方法的例子21 什么是Java静态同步方法 如果将任何静态方法设置为synchronized(同步),则锁定的是类而不是对象。 2 没有静态同步方法的问题 假设有两个共享类(例如:Table类)的对象,分别名为object1和object2。在使用同步方法和同步代码块的情况下,t1和t2或t3和t4之间不会存在干扰,因为t1和t2都引用了一个具有单个锁,但是t1和t3或t2和t4之间可能存
问题内容: 这是我在此链接上找到的一段文字。 “避免锁定静态方法 最糟糕的解决方案是将“ synchronized”关键字放在静态方法上,这意味着它将锁定此类的所有实例。” 为什么同步静态方法会锁定该类的所有实例?它不应该锁定课程吗? 问题答案: 这是我的测试代码,表明您是正确的,并且本文有点过分谨慎: 印刷品: 因此与实例的方法无关… 当然,如果整个系统都使用这些方法,那么您可以期望它们对多线程