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 就是通过防止线程干扰来防止数据不一致。
- 该方法的最大缺点是所有进程都处于等待状态,因此队列中的最后一个进程必须等到所有其他进程都完成。