本文讨论了 Java 中线程同步的重要性以及如何在程序中实现线程同步。
当您的程序有多个线程时,当不同的线程尝试访问相同的资源或同时执行相同的操作时,可能会出现问题。 这种情况会导致错误和并发问题。 让我们以一个示例为例,您的程序中有两个线程试图读取/写入文本文件。 当两个线程都在写入文件时,一个线程的数据可能会被另一个线程覆盖,并且在读取文件时会发现相同的问题。
因此,线程同步是必需的,以便多个线程在任何给定时间点一次访问一个线程。
为什么要使用线程同步?
- 防止线程干扰
- 避免一致性问题和并发问题
- 防止数据丢失
线程同步有互斥和线程间通信两种类型。
- 互斥
- 同步方法。
- 同步块。
- 静态同步。
- 合作(Java 中的线程间通信)
同步块
同步块用于线程同步。
synchronized关键字用于标识 Java 中的同步块,并基于某些对象进行同步。 其背后的主要概念是,在同一对象上同步的所有同步块一次只能在其中一个线程内执行,这会阻止多个线程同时运行和执行。 尝试进入同步块的所有其他线程将被阻止,直到同步块内的线程退出该块为止。
共享资源保留在此同步块内,以便在给定时间点只有一个线程可以访问特定资源。
同步块的语法如下所示:
synchronized(referencetoobject) {// Shared variables and other shared resources are placed here}
监视器
在尝试理解和实现 Java 同步时,监视器的概念很重要。
- Java 中的每个对象都与一个监视器关联
- 线程可以锁定或解锁监视器
- 在给定时间,只有一个线程可以拥有监视器。
- 一次只能有一个线程可以锁定监视器
线程同步示例
//We write a program with a simple counter execution.class Countings {public void printing() {try {for(int i = 5; i > 0; i--) {System.out.println( i );}} catch (Exception e) {System.out.println("Thread interrupted.");}}}class Threadings extends Thread {private Thread thrd;private String thrdName;Countings gg;Threadings( String name, Countings abc) {thrdName = name;gg = abc;}public void run() {gg.printing();System.out.println("Thread " + thrdName + " exiting.");}public void start () {System.out.println("Starting " + thrdName );if (thrd == null) {thrd = new Thread (this, thrdName);thrd.start ();}}}public class Tests {public static void main(String args[]) {Countings gg = new Countings();Countings T1 = new Countings ( "Thread - 1 ", gg );Countings T2 = new Countings ( "Thread - 2 ", gg );T1.start();T2.start();// threads take some time to endtry {T1.join();T2.join();} catch ( Exception e) {System.out.println("Interrupted");}}}
输出:(每次运行都会产生不同的结果)
Starting Thread - 1Starting Thread - 25435214Thread Thread - 1 exiting.321Thread Thread - 2 exiting.
相同的示例,但是这次具有线程同步:
class Countings {public void printings() {try {for(int i = 5; i > 0; i--) {System.out.println( i );}} catch (Exception e) {System.out.println("Thread interrupted.");}}}class Threadings extends Thread {private Thread t;private String thrdName;Countings gg;Threadings( String name, Countings abc) {thrdName = name;gg = abc;}public void run() {synchronized(gg) {gg.printings();}System.out.println("Thread " + threadName + " exiting.");}public void start () {System.out.println("Starting " + thrdName );if (thrd == null) {thrd = new Thread (this, thrdName);thrd.start ();}}}public class Testings{public static void main(String args[]) {Countings gg = new Countings();Threadings T1 = new Threadings ( "Thread - 1 ", gg );Threadings T2 = new Threadings ( "Thread - 2 ", gg );T1.start();T2.start();// wait for threads to endtry {T1.join();T2.join();} catch ( Exception e) {System.out.println("Interrupted");}}}
输出:(我们看到的输出是同步的,并且每次执行程序都是相同的)
Starting Thread - 1Starting Thread - 254321Thread Thread - 1 exiting.54321Thread Thread - 2 exiting.
