ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Java 线程同步 > 原文: [https://javatutorial.net/java-thread-synchronization](https://javatutorial.net/java-thread-synchronization) 本文讨论了 Java 中线程同步的重要性以及如何在程序中实现线程同步。 当您的程序有多个线程时,当不同的线程尝试访问相同的资源或同时执行相同的操作时,可能会出现问题。 这种情况会导致错误和并发问题。 让我们以一个示例为例,您的程序中有两个线程试图读取/写入文本文件。 当两个线程都在写入文件时,一个线程的数据可能会被另一个线程覆盖,并且在读取文件时会发现相同的问题。 因此,线程同​​步是必需的,以便多个线程在任何给定时间点一次访问一个线程。 为什么要使用线程同步? * 防止线程干扰 * 避免一致性问题和并发问题 * 防止数据丢失 线程同步有互斥和线程间通信两种类型。 * 互斥 * 同步方法。 * 同步块。 * 静态同步。 * 合作(Java 中的线程间通信) ## 同步块 同步块用于线程同步。 `synchronized`关键字用于标识 Java 中的同步块,并基于某些对象进行同步。 其背后的主要概念是,在同一对象上同步的所有同步块一次只能在其中一个线程内执行,这会阻止多个线程同时运行和执行。 尝试进入同步块的所有其他线程将被阻止,直到同步块内的线程退出该块为止。 共享资源保留在此同步块内,以便在给定时间点只有一个线程可以访问特定资源。 同步块的语法如下所示: ```java synchronized(referencetoobject) { // Shared variables and other shared resources are placed here } ``` ## 监视器 在尝试理解和实现 Java 同步时,监视器的概念很重要。 * 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 end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println("Interrupted"); } } } ``` 输出:(每次运行都会产生不同的结果) ```java Starting Thread - 1 Starting Thread - 2 5 4 3 5 2 1 4 Thread Thread - 1  exiting. 3 2 1 Thread Thread - 2  exiting. ``` 相同的示例,但是这次具有线程同步: ```java 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 end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println("Interrupted"); } } } ``` 输出:(我们看到的输出是同步的,并且每次执行程序都是相同的) ```java Starting Thread - 1 Starting Thread - 2 5 4 3 2 1 Thread Thread - 1  exiting. 5 4 3 2 1 Thread Thread - 2  exiting. ```