同步是将对共享资源的访问限制为仅一个线程的能力。当两个或多个线程需要访问共享资源时,必须有某种机制使得共享资源只能由一个线程使用。我们可以实现它的过程称为同步。
让我们借助示例来理解这一点。 假设您想计算针对特定 URL 获得的请求数。如果同时收到两个请求,那么 count 可能会不一致。
package org.arpit.java2blog; public class RequestCounter { private int count; public int incrementCount() { count++; return count; } }
例如: 线程 T1 看到 count 为 20 并递增到 21。同时线程 t2 也看到 count 为 20 并将其递增到 21。这表明 count 变得不一致。
您可以使用两种方式实现同步。
您可以使整个 incrementCount() 方法同步,因此没有两个线程可以并行访问它。
package org.arpit.java2blog; public class RequestCounter { private int count; public synchronized int incrementCount() { count++; return count; } }
例如: 线程 T1 看到计数为 20 并将其增加到 21。同时,线程 t2 现在将看到计数为 21 并将其增加到 22。
您可以在 incrementCount() 方法中使用 block 来同步临界区,这样就没有两个线程可以同时访问 block。
package org.arpit.java2blog; public class RequestCounter { private int count; public int incrementCount() { synchronized (this) { count++; return count; } } }
java中有两种类型的锁定。
对象级锁定
类级别锁定
对象级锁定意味着您希望同步非静态方法或块,以便该实例一次只能由一个线程访问。如果要保护非静态数据,则使用它。
您可以通过以下方式实现对象级锁定。
public synchronized int incrementCount() { }
public int incrementCount() { synchronized (this) { count++; return count; }
private final Object lock=new Object(); public int incrementCount() { synchronized (lock) { count++; return count; }
类级锁定意味着您要同步静态方法或块,以便整个类只能由一个线程访问。如果您有 10 个类实例,则只有一个线程一次只能访问任何一个实例的一种方法或块。如果要保护静态数据,则使用它。
这可以通过以下方式实现:
public static synchronized int incrementCount() { }
public int incrementCount() { synchronized (RequestCounter.class) { count++; return count; }
private final static Object lock=new Object(); public int incrementCount() { synchronized (lock) { count++; return count; }
是的,由于两个线程将获取不同对象的锁,因此它们可以同时执行而不会出现任何问题。
是的,因为一个线程需要锁才能进入同步块,而第二个线程将执行不需要任何锁的非同步方法,所以它可以并发执行。
是的,从另一个同步方法调用同步方法是安全的,因为当您调用同步方法时,您将获得对该对象的锁定,而当您调用同一类的另一个同步方法时,执行是安全的,因为它已经锁定这个对象。 例如:
public synchronized void method1() { method2(); // some code } public synchronized void method2() { // some code }
你实际上正在这样做。
public void method1() { synchronized (this) { method2(); // some code } } public void method2() { synchronized (this) { // some code } }
这里如果任何线程从method1调用method2,它已经锁定了这个对象,因此执行是安全的。
原文链接:https://codingdict.com/