在多线程编程中,多个线程同时运行并访问公共资源。为避免死锁,我们必须确保一次必须由一个线程共享资源,否则可能产生奇怪或不可预见的结果。此过程称为同步。在本文中,我们将讨论如何在Java中实现线程同步?
让我们通过一个例子来理解这一点。有两个线程正在访问和写入公共文件output.txt。如果不使用同步,则一个线程在文件中写入少量单词,而另一个线程开始向文件写入。结果文件将包含两个线程写入的随机内容。通过同步,如果一个线程正在写入文件,则文件将被锁定(处于LOCK模式),并且直到第一个线程完成其工作之前,其他线程或进程都无法访问该文件。
考虑代码,没有同步,
class print{ public void printMSG(String s){ for(int i=1;i<=5;i++) { System.out.println(s); try { Thread.sleep(1000); //用于将当前执行休眠1秒 } catch (Exception e) { System.out.println(e); } } } } class one extends Thread{ print t; one(print t){ this.t=t; } public void run(){ t.printMSG("Hi"); } } class two extends Thread{ print t; two(print t){ this.t=t; } public void run() { t.printMSG("Bye"); } } public class ExSynchronization { public static void main(String[] args) { print t=new print(); one ob=new one(t); two o2=new two(t); ob.start(); o2.start(); } }
输出结果
Hi Bye Bye Hi Hi Bye Hi Bye Hi Bye
注意:此输出是随机的。
在此程序中,我们设计了两个线程来访问一个公共函数printMSG()
。当我们运行这段代码时,我们可能会得到不需要的输出,如上所示。
为了同步输出,我们将使用同步方法。这将为共享资源锁定对象。我们可以通过在共享方法中添加synced关键字来做到这一点。
让我们看下面的同步代码,
class print{ synchronized public void printMSG(String s){ for(int i=1;i<=5;i++) { System.out.println(s); try { Thread.sleep(1000); //用于将当前执行休眠1秒 } catch (Exception e) { System.out.println(e); } } } } class one extends Thread{ print t; one(print t){ this.t=t; } public void run(){ t.printMSG("Hi"); } } class two extends Thread{ print t; two(print t){ this.t=t; } public void run() { t.printMSG("Bye"); } } public class ExSynchronization { public static void main(String[] args) { print t=new print(); one ob=new one(t); two o2=new two(t); ob.start(); o2.start(); } }
输出结果
Hi Hi Hi Hi Hi Bye Bye Bye Bye Bye
注意:线程可以以任何顺序启动。