Sync统一化 Java

什么是 Sync统一化 Java?

In Java同步是指控制多个线程对任何共享资源的访问的能力。当我们希望只允许一个线程访问共享资源时,同步是一种理想的选择。

这种执行方式通常被称为“异步”编程。这些处理器上还有线程,它们是可以同时执行指令的轻量级进程。

有哪些 Sync汉化

有两种类型的同步方法 Java:

1) 进程同步

2) 线程同步。

让我们学习一下 Thread 和 进程同步 详细。

进程同步: 它管理程序之间的同步。例如,诸如“Microsoft Word' 和 'Acrobat reader' 作为单独的进程运行。

线程同步: 两个或多个线程同时执行关键资源被称为线程 Sync同步。您可以进一步分组为“互斥”和线程间通信。

什么是锁定 Java?

锁定 Java 是围绕称为监视器或锁的内部实体构建的。所有对象都具有与之关联的锁。因此,需要一致访问对象字段的线程必须在访问它们之前获取对象的锁,并在工作完成后释放锁。这确保一次只有一个线程访问共享数据。

具有同步的多线程程序

多线程程序 是一种方法或块,使用“synchronized”关键字指示,可以防止共享同一资源的其他线程的干扰。

使用同步方法

任何声明为同步的方法都称为同步方法。它还用于锁定任何共享资源的对象。因此,当线程调用同步方法时。它会自动占有该对象的锁,并在完成任务后释放它。

请注意: synchronized 关键字不能用于类和变量。只有方法和块才能与该关键字一起使用。

为什么使用 Sync标准化方法?

  • 它用于锁定任何共享资源的对象。
  • 每当调用同步方法时,对象就会获得锁。
  • 直到线程完成其功能后,锁才会释放

语法:

Acess_modifiers synchronized return_type method_name (Method_Parameters) {
}
class MathService {
    synchronized void getSumOfArray(int[] numbers) {
     int sum = 0;

         for (int number : numbers) {
             System.out.println(Thread.currentThread()
                     .getName()
                     + " adds "
                     + sum + " to "
                     + number + " to get -> "
                     + (sum += number));

             try {
                 Thread.sleep(500);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
         }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
    }
}

代码说明:

运行此示例,可观察到线程 0 首先获取 mathService 对象的锁,并独占使用此锁,直到执行完成。线程 0 和 1 在此代码中没有交错。输出如下所示。

输出:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

使用同步块

假设您不想同步整个方法。相反,您想同步几行代码。那时, Sync同步块帮助同步选定的 Java 码。 Sync同步方法锁是在方法上访问的,而同步块锁是在对象上访问的。

class MathService {
    void getSumOfArray(int[] numbers) {
        synchronized (this){
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
    }
}

代码说明:

运行此代码后,您会注意到它没有任何干扰。在同步方法中,锁由方法应用,但在同步块中,锁由对象应用。确保输出如下所示。

输出:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

代码说明:

当你运行这段代码时,你会注意到它在没有任何干扰的情况下工作,这正是我们所期望的。在synchronized方法中,锁是由方法应用的,但在synchronized块方法中,锁是由对象应用的。

使用静态同步

In Java 同步,如果有多个对象,则两个线程可能会获取锁并进入同步块或块,每个对象都有一个单独的锁。为了避免这种情况,可以使用静态同步。 Sync静态方法前将使用 hronized 关键字。

请注意: 静态同步中,锁访问是在类上,而不是对象和方法上。

演示多个对象锁定问题的代码

class MathService {
    synchronized void getSumOfArray(int[] numbers) {
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();
        MathService mathService1 = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));
        Thread threadThree = new Thread(() ->
                mathService1.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadFour = new Thread(() ->
                mathService1.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
        threadThree.start();
        threadFour.start();
    }
}

代码说明:

当我们创建 `MathService` 的另一个实例时,我们会在线程中引入干扰,因为它们将与这两个对象交错。请注意,线程 `0` 和线程 `2` 与这两个对象交错,而线程 `1` 和 `3` 与这两个对象交错。

输出:

Thread-0 adds 0 to 10 to get -> 10
Thread-2 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-2 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-2 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-3 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-3 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63
Thread-3 adds 41 to 22 to get -> 63

使用同步静态方法的相同代码

class MathService {
    synchronized static void getSumOfArray(int[] numbers) {
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();
        MathService mathService1 = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));
        Thread threadThree = new Thread(() ->
                mathService1.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadFour = new Thread(() ->
                mathService1.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
        threadThree.start();
        threadFour.start();
    }
}

运行上述代码,注意我们现在已经消除了线程干扰。代码的输出如下所示。

输出:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-3 adds 0 to 20 to get -> 20
Thread-3 adds 20 to 21 to get -> 41
Thread-3 adds 41 to 22 to get -> 63
Thread-2 adds 0 to 10 to get -> 10
Thread-2 adds 10 to 11 to get -> 21
Thread-2 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

使用同步的优点

使用并发应用程序的优点如下:

  • 同步的主要目的 Java 就是通过防止线程干扰来防止数据不一致。
  • 中的synchronized关键字 Java 提供锁定,确保对共享资源的互斥访问并防止数据竞争。
  • 它还可以防止代码语句被重新排序 编译,如果我们不使用 volatile 或 synchronized 关键字,这可能会导致细微的并发问题。
  • Synchronized 关键字从主内存而不是缓存中读取数据并释放锁。
  • 它还会清除主内存中的写入操作,从而消除内存不一致错误。

缺点 Sync同步机制

Sync同步化机制绩效不佳。

举个例子

  • 假设有五个进程,A1、A2、A3、A4 和 A5。
  • 它们正在等待共享资源一次访问一个线程。
  • 所有进程都处于等待状态,因此队列中的最后一个进程必须等到所有其他进程都完成。

总结

  • Sync同步是指控制多个线程对任何共享资源的访问的能力。
  • Java 有两种类型的同步方法: 1) 进程同步和 2) 线程同步。
  • 锁定 Java 是围绕称为监视器或锁的内部实体构建的。
  • 多线程程序是一种方法或块,使用“synchronized”关键字指示,可以防止共享同一资源的其他线程的干扰。
  • 任何声明为同步的方法都称为同步方法。
  • In Java,同步方法锁是在方法上访问的,而同步块锁是在对象上访问的。
  • 静态同步中,锁访问是在类上,而不是对象和方法上。
  • 同步的主要目的 Java 就是通过防止线程干扰来防止数据不一致。
  • 该方法的最大缺点是所有进程都处于等待状态,因此队列中的最后一个进程必须等到所有其他进程都完成。