Java 使用同步(锁定)时,锁定对象首选为静态还是非静态?

Java 使用同步(锁定)时,锁定对象首选为静态还是非静态?,java,synchronization,Java,Synchronization,当使用这样的东西时: private final Object lock = new Object() 静态的和非静态的有什么区别吗 非静态对象可以锁定静态方法吗?反之亦然?这取决于情况。你想做什么?如果锁应该全局共享,那么它可能应该是静态的。如果您尝试同步的对象是非静态的,那么您可能不应该使用静态锁定对象,因为这样会阻止对单独实体的同时访问。最大的区别是,锁定非静态对象意味着您可能锁定两个不同的对象,因此不提供任何互斥。如果互斥只需要在对象级别提供,那么这可能就是您想要的。(事实上,这就是同

当使用这样的东西时:

private final Object lock = new Object()
静态的和非静态的有什么区别吗


非静态对象可以锁定静态方法吗?反之亦然?

这取决于情况。你想做什么?如果锁应该全局共享,那么它可能应该是静态的。如果您尝试同步的对象是非静态的,那么您可能不应该使用静态锁定对象,因为这样会阻止对单独实体的同时访问。

最大的区别是,锁定非静态对象意味着您可能锁定两个不同的对象,因此不提供任何互斥。如果互斥只需要在对象级别提供,那么这可能就是您想要的。(事实上,这就是同步(非静态)方法时发生的情况:您正在
This
上同步,它肯定不是静态对象。)

如果您使用的是非静态锁,对象的每个实例都会有一个不同的锁对象,这可能是一个更细粒度的调用:

synchronized(this) {

}
也就是说:您只锁定来自同一对象内的其他访问。使用静态锁,类的每个实例都共享该锁对象。因此,在任何给定时间,只有一个线程可以访问同步块

所以这取决于你在做什么。在前一种情况下,分配锁对象是没有意义的,除非有多个锁保护较小的数据子集。在后一种情况下,您基本上(同样是更细粒度的)是这样做的:

synchronized(MyObject.class) {

}
也就是说,您正在锁定所有访问,而不管您使用的是相同的对象还是不同的对象进行访问


这将取决于您试图完成的任务、锁定的对象以及这些锁定的使用方式。如果要保护每个实例的状态,可能需要一个每个实例(非静态)的锁对象。如果您要保护全局状态,您需要一个所有人共享的静态锁对象。

这完全取决于您要保护的对象。您需要了解lock对象的用途。
static
意味着在同一类的所有实例中,只会创建该对象的一个副本。