Java线程同步
时间:2020-02-23 14:37:16 来源:igfitidea点击:
本文讨论了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 end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println("Interrupted"); } } }
输出:(每次运行产生不同的结果)
Starting Thread - 1 Starting Thread - 2 5 4 3 5 2 1 4 Thread Thread - 1 exiting. 3 2 1 Thread 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 end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println("Interrupted"); } } }
输出:(我们可以看到输出是同步的,每次执行程序时都是相同的)
Starting Thread - 1 Starting Thread - 2 5 4 3 2 1 Thread Thread - 1 exiting. 5 4 3 2 1 Thread Thread - 2 exiting.