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.

