在Java中,同步的代码块一次只能由一个线程执行。此外,java支持多个线程同时执行。这可能导致两个或多个线程同时访问相同的字段或对象。

同步是使执行中的所有并发线程保持同步的过程。同步可避免由于共享内存视图不一致而导致的内存一致性错误。当方法声明为synchronized时 ; 该线程持有监视器或锁定对象为这个方法的对象。如果另一个线程正在执行synchronized方法,则您的线程将被阻塞,直到该线程释放监视器。

请注意,我们可以synchronized在类中使用关键字来定义方法或块。synchronized关键字不能与类定义中的变量或属性一起使用。

1. Java中的对象级锁定

对象级锁是机制,当我们要同步非静态方法或者非静态代码块,使得只有一个线程就可以在类的给定实例执行的代码块。应始终这样做以使实例级数据线程安全

对象级锁定可以按如下方式完成:

对象级锁定的各种方法

public class DemoClass

{

    public synchronized void demoMethod(){}

}

 

or

 

public class DemoClass

{

    public void demoMethod(){

        synchronized (this)

        {

            //other thread safe code

        }

    }

}

 

or

 

public class DemoClass

{

    private final Object lock = new Object();

    public void demoMethod(){

        synchronized (lock)

        {

            //other thread safe code

        }

    }

}9

2. Java中的类级别锁定

类级别锁定可防止多个线程synchronized在运行时的所有可用类实例中的块中输入。这意味着如果在运行时有100个实例DemoClass,则一次只能有一个线程demoMethod()在任何一个实例中执行,而其他所有实例都将被锁定用于其他线程。

应始终进行类级别锁定以使静态数据线程安全。我们知道static关键字将方法的数据关联到类级别,因此在静态字段或方法中使用锁定使其在类级别上进行。

类级锁定的各种方法

public class DemoClass

{

    public synchronized void demoMethod(){}

}

 

or

 

public class DemoClass

{

    public void demoMethod(){

        synchronized (this)

        {

            //other thread safe code

        }

    }

}

 

or

 

public class DemoClass

{

    private final Object lock = new Object();

    public void demoMethod(){

        synchronized (lock)

        {

            //other thread safe code

        }

    }

}

3.对象级锁定与类级别锁定 - 重要说明

  1. Java中的同步保证没有两个线程可以同时或同时执行同步方法,这需要相同的锁定。
  2. synchronizedkeyword只能用于方法和代码块。这些方法或块可以是静态的还是非静态两种。
  3. 当线程进入Java synchronized方法或阻塞时,它获取一个锁,每当它离开同步方法或阻塞时,它就会释放锁。即使线程在完成后或由于任何错误或异常而离开同步方法,锁也会被释放。
  4. Java synchronized关键字本质上是可重入的,这意味着如果同步方法调用另一个需要相同锁定的同步方法,那么持有锁定的当前线程可以在不获取锁定的情况下进入该方法。
  5. NullPointerException如果synchronized块中使用的对象为null,则抛出Java同步。例如,在上面的代码示例中,如果将lock初始化为null,synchronized (lock)则将抛出“ ” NullPointerException
  6. Java中的同步方法会为您的应用程序带来性能成本。因此,在绝对需要时使用同步。另外,请考虑使用同步代码块来仅同步代码的关键部分。
  7. 静态同步和非静态同步方法可能同时或同时运行,因为它们锁定在不同的对象上。
  8. 根据Java语言规范,您不能将synchronized关键字与构造函数一起使用。这是非法的,会导致编译错误。
  9. 不要在Java中的同步块上的非最终字段上进行同步。因为非最终字段的引用可能随时改变,然后不同的线程可能在不同的对象上同步,即根本不同步。
  10. 不要使用字符串文字,因为它们可能会被引用到应用程序中的其他位置并且可能导致死锁。使用new关键字创建的字符串对象可以安全使用。但作为最佳实践,请在我们要保护的共享变量本身上创建一个新的