我有多个方法,我希望有静态锁,这样没有两个对象可以访问一个方法,但同时不同的方法不会被这些对象锁定,并且可以独立运行。
class A {
private static final A lock1 = new A();
private static final B lock2 = new B();
public void method1() {
synchronized (lock1) {
// do something
}
}
public void method2() {
synchronized (lock2) {
// do something
}
}
}
现在我希望这两个方法在被锁定时彼此独立,但同时我希望同一类的多个示例在单个方法中被锁定。
如何做到这一点?通过使用不同的类?这样做能做到这一点吗?
3条答案
按热度按时间wbgh16ku1#
首先,这就足够了:
然后,随着你的实施,,
method1
及method2
相互独立,但只有一个示例method1
或method2
可以在的所有示例中运行A
. 如果希望允许的不同并发示例A
以便method1
及method2
多个不同的示例可以并发运行,只需声明锁而不需要static
.换句话说:如果
a1
及a2
都是A
:具有
static
锁,如果a1.method1
正在运行,a2.method1
无法由其他线程运行没有静电,
a1.method1
只能由一个线程运行。a1.method1
及a2.method1
可以同时运行。eqoofvh92#
静电锁
如果锁定的对象位于静态字段中,则该特定类的所有示例都将共享该锁定。这意味着如果从该类创建的一个对象正在访问该类
static
lock,则从该类创建的另一个对象无法访问该锁。非静态锁
如果类有一个非静态锁,那么每个示例都有自己的锁,因此只有对同一对象的方法调用才会相互锁定。
例如,使用静态锁定对象时:
线程1调用
obj01.doSomething()
线程2调用obj01.doSomething()
,将必须等待线程1完成线程3调用
obj02.doSomething()
,还必须等待线程1(可能还有线程2)完成。使用非静态锁定对象时:
线程1调用
obj01.doSomething()
线程2调用obj01.doSomething()
,将必须等待线程1完成线程3调用
obj02.doSomething()
,它可以继续,而不考虑线程1和线程2,因为这是一个新对象,它不依赖于类。非静态锁基本上是对象级锁。静态锁是类级锁
对象级锁
java中的每个对象都有一个唯一的锁。如果线程想要在给定对象上执行同步方法,首先它必须获得该对象的锁。一旦线程获得了锁,就可以在该对象上执行任何同步方法。一旦方法执行完成,线程就会自动释放锁。
输出将是,,
类级锁
java中的每个类都有一个唯一的锁,它只是一个类级锁。如果线程想要执行静态同步方法,那么该线程需要类级锁。一旦线程获得了类级锁,就可以执行该类的任何静态同步方法。一旦方法执行完成,线程就会自动释放锁。
输出如下所示,
当前情景
在这里,您有两个方法,如果一个方法使用一个锁访问,另一个使用另一个锁,那么在您的实现中,您可以有两个对象使用彼此的方法,但不能使用相同的方法。
这是可能的,但不是这个
你
obj02
必须等到obj01
完成这个方法。vof42yt13#
锁不是用于方法的。锁用于数据。使用互斥锁的全部目的是确保不同的线程总能看到一些共享数据的一致视图。
您的代码示例显示了两个锁,但没有显示锁应该保护的数据。这样更好:
我的
Example
类有两个独立的变量组;a
,b
,及c
,及alpha
,beta
,及gamma
. 每个独立组都有自己的独立锁。任何访问“r-state”变量的方法都应该是synchronized (lockR)...
,同样适用于“g状态”变量和lockG
.如果一个方法需要同时访问两个组,那么它必须锁定这两个锁。但是请注意!这可能表明这两个群体并不是真正独立的。如果它们之间存在任何依赖关系,那么实际上应该只有一个锁。
还请注意,我删除了
static
从这个例子。那纯粹是无缘无故的改变。我憎恶static
. 你也应该厌恶它,但这是另一个与锁定无关的主题。