实现Java中的非静态即席锁

huangapple go评论61阅读模式
英文:

Implementing Non-static Ad Hoc Locks in Java

问题

我正在阅读由Cay S. Horstmann撰写的《Core Java I》一书,他在第577页提到了关于“临时”锁的内容:

有时您会找到“临时”锁,例如

public class Bank
{
    private double[] accounts;
    private var lock = new Object();
    
    // . . .
    
    public void transfer(int from, int to, int amount)
    {
        synchronized (lock) // 一个临时锁
        {
            accounts[from] -= amount;
            accounts[to] += amount;        
        }
        
        System.out.println(. . .);
    }
}

在这里,锁对象仅用于使用每个Java对象都具有的锁。

正如您所知,锁定是一种防止其他线程执行特定代码块的机制。如果锁不是静态的(如上面的代码部分所述),任何拥有自己锁的线程都不会了解其他线程的锁情况。换句话说,为了执行锁定,锁在所有其他线程之间必须是唯一的。根据这个定义,锁应该是静态的吗?

提前致谢。

英文:

I am reading the book "Core Java I" written by Cay S. Horstmann and he mentions about the ad hoc locks as such in page 577:

> You will sometimes find “ad hoc” locks, such as

public class Bank
{
	
	private double[] accounts;
	
	private var lock = new Object();
	
	// . . .
	
	public void transfer(int from, int to, int amount)
	{
		synchronized (lock) // an ad-hoc lock
		{
			accounts[from] -= amount;
			accounts[to] += amount;		
		}
		
		System.out.println(. . .);
	}
}

> Here, the lock object is created only to use the lock that every Java
> object possesses.

As you know, locking is a mechanism that prevents other threads to execute specific code block. If the lock is not static (as mentioned in the code section above) any thread that has own its lock, and do not have any idea about the locks of the other threads. In other words, in order to perform the locks, locks shall be unique among all other threads. By this definition, shall lock be static?

Thanks in advance.

答案1

得分: 0

在您的示例中,类似于锁并不是静态的。原因在于它不是类的静态值 - 这将使用 static 修饰符。

如果一个线程“遇到”一个synchronized块,该线程将尝试获取引用的对象。如果没有提供对象,则将锁定包含该方法的对象。这种锁是对象特定的,在线程离开该代码块时会被释放。

当调用的方法本身是静态的时,也会出现静态锁:

public static synchronized void soSomething() {
   ...
}

在这些情况下,将锁定周围类的Class对象,这意味着只有一个线程可以访问静态同步类内的任何方法,即使逻辑上可以同时访问这些方法。

如果希望同时锁定特定的功能子集,并且存在多个这样的子集,应该彼此独立地锁定,或者如果锁应该明确地被隐藏,以便不会以意外的方式锁定/解锁,那么创建临时锁是有意义的。 "不要暴露您的锁" 是使用 Lombok 的 @Synchronized 注解来进行锁定的正面论据。

https://projectlombok.org/features/all

英文:

A lock like in your example is not static. The reason is that it is not a static value of the class - that would have the static modifier.

If a thread 'encounters' a synchronized block, the thread will try to acquire the referenced object. If none is provided, then the object containing the method will be locked. Such a lock is object specific, and is returned, when the thread leaves that code block.

Static locks can also occure, when the methods called are static themselves:

public static synchronized void soSomething() {
   ...
}

In those cases, the Class object of the surrounding class is locked, which means that only one thread can ever access any method within a class that is static synchronized, even if the methods could logically be accessed simultaniously.

An 'ad hoc' lock makes sense, if a specific subset ob functionality is supposed to be locked simultaniously, but there are multiple such subsets, which should lock independent from each other, or if the lock should explicitly be hidden, so it is not locked/unlocked in an unintended way. 'Do not expose your locks' is a pro argument for using lombok's @Synchronized annotation for locks.

https://projectlombok.org/features/all

huangapple
  • 本文由 发表于 2020年10月1日 17:02:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64152146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定