gpt4 book ai didi

java - 仅在访问同一对象的同一方法时才锁定线程

转载 作者:行者123 更新时间:2023-11-29 07:26:56 24 4
gpt4 key购买 nike

我有一个对象,其中包含我的多线程项目的常用方法。一些方法是同步的。我的问题是当其中一个线程访问同步方法而另一个线程访问另一个同步方法时。这将使其中一个线程等待另一个线程。我只想在访问相同的同步方法时锁定线程,但我不知道如何。我最近发现关键字 synchronized。

这是我的一种方法。

public synchronized static void writeError(Exception err){

String time = longDate();//here will get personalized current date
//longDate is not synchronized.

try {

FileWriter path = new FileWriter("ERROR - " + time + ".txt",true);

err.printStackTrace(new PrintWriter(path));

path.flush();

} catch (IOException e) {}

}

对这种方法有什么想法吗?

最佳答案

所以synchronized总是需要一个对象来操作。所有共享同一对象的同步 block 都是互斥的(即一次只有一个线程可以进入 block )。将 synchronized 放在方法声明中是简写,例如方法等于 synchronized(this) 静态方法等于 synchronized(Foo.class)(其中 Foo 是包含静态方法的类)。

知道了这一点,您就可以轻松地创建多个要同步的对象,控制哪些方法可以同时运行,哪些不能。

允许method3与method1或method2同时运行的示例类,但method1和method2是互斥的。此外,一次只能有一个线程运行每个方法。

public class Foo {
private final static Object lock1 = new Object();
private final static Object lock2 = new Object();

public static void method1() {
synchronized(lock1) {
...
}
}

public static void method2() {
synchronized(lock1) {
...
}
}

public static void method3() {
synchronized(lock2) {
...
}
}
}

还要注意静态与非静态。这里的方法是静态的,锁也是静态的,所以一切都很好。如果这些方法是非静态的,它也会阻止在不同的对象上调用这些方法,这可能不是您想要的。在那种情况下,使锁成为非静态锁会使每个 Foo 实例都像前面描述的那样工作,但是在 foo1.method1() 的情况下不会有锁,并且foo2.method2() 因为它们不会在同一个对象上同步。

正如 Shubham Kadlag 的回答所示,synchronized 远非 Java 拥有的唯一并发工具。 java.util.concurrent.locks 包有用于锁定的类(而 synchronized 是一种内置机制)。例如,ReentrantReadWriteLock 允许您处理多个线程可以同时执行某些操作(读取),但一次只允许一个线程执行修改操作(写入)的情况。它们还允许您为锁定设置超时,而 synchronized 将愉快地永远等待(并不是通常需要 tryLock(),因为如果您陷入僵局)。

然后您意识到手动锁定无论如何都是笨蛋,并发现 java.util.concurrent 有许多类可以对您隐藏锁定并提供各种高级功能。

关于java - 仅在访问同一对象的同一方法时才锁定线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50527338/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com