无涯教程-Java - 线程同步函数

30 阅读2分钟

当无涯教程在程序中启动两个或多个线程时,可能会出现多个线程尝试访问同一资源,最终由于并发问题,它们可能产生无法预料的情况。如果多个线程试图在同一文件中写入数据,则它们可能会破坏数据,因为其中一个线程可以覆盖数据,或者当一个线程打开同一文件时,另一个线程可能正在关闭同一文件。

Java编程语言提供了一种非常方便的方法,可以通过使用 synchronized 块来创建线程并同步其任务,以下是同步语句的一般形式-

synchronized(objectidentifier) {
   //Access shared variables and other shared resources
}

在这里, objectidentifier 是对对象的引用,该对象 的锁与同步语句表示的监视器相关联。

未同步多线程示例

这是一个简单的示例,它可以按顺序打印计数器值,也可以不按顺序打印,并且每次运行它时,它的输出值都不一样。

class PrintDemo {
   public void printCount() {
      try {
         for(int i = 5; i > 0; i--) {
            System.out.println("Counter   ---   "  + i );
         }
      } catch (Exception e) {
         System.out.println("Thread  interrupted.");
      }
   }
}

class ThreadDemo extends Thread { private Thread t; private String threadName; PrintDemo PD;

ThreadDemo( String name, PrintDemo pd) { threadName = name; PD = pd; }

public void run() { PD.printCount(); System.out.println("Thread " + threadName + " exiting."); }

public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } }

public class TestThread { public static void main(String args[]) {

  </span><span class="typ">PrintDemo</span><span class="pln"> PD </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PrintDemo</span><span class="pun">();</span><span class="pln">

  </span><span class="typ">ThreadDemo</span><span class="pln"> T1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ThreadDemo</span><span class="pun">(</span><span class="pln"> </span><span class="str">"Thread - 1 "</span><span class="pun">,</span><span class="pln"> PD </span><span class="pun">);</span><span class="pln">
  </span><span class="typ">ThreadDemo</span><span class="pln"> T2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ThreadDemo</span><span class="pun">(</span><span class="pln"> </span><span class="str">"Thread - 2 "</span><span class="pun">,</span><span class="pln"> PD </span><span class="pun">);</span><span class="pln">

  T1</span><span class="pun">.</span><span class="pln">start</span><span class="pun">();</span><span class="pln">
  T2</span><span class="pun">.</span><span class="pln">start</span><span class="pun">();</span><span class="pln">

  </span><span class="com">//wait for threads to end</span><span class="pln">
     </span><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
     T1</span><span class="pun">.</span><span class="kwd">join</span><span class="pun">();</span><span class="pln">
     T2</span><span class="pun">.</span><span class="kwd">join</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="typ">Exception</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
     </span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Interrupted"</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

} }

每次您运行该程序时,都会产生不同的输出-

Starting Thread - 1
Starting Thread - 2
Counter   ---   5
Counter   ---   4
Counter   ---   3
Counter   ---   5
Counter   ---   2
Counter   ---   1
Counter   ---   4
Thread Thread - 1  exiting.
Counter   ---   3
Counter   ---   2
Counter   ---   1
Thread Thread - 2  exiting.

同步多线程示例

这是相同的示例,它按顺序打印计数器值,并且每次运行它时,它都会产生相同的输出。

class PrintDemo {
   public void printCount() {
      try {
         for(int i = 5; i > 0; i--) {
            System.out.println("Counter   ---   "  + i );
         }
      } catch (Exception e) {
         System.out.println("Thread  interrupted.");
      }
   }
}

class ThreadDemo extends Thread { private Thread t; private String threadName; PrintDemo PD;

ThreadDemo( String name, PrintDemo pd) { threadName = name; PD = pd; }

public void run() { synchronized(PD) { PD.printCount(); } System.out.println("Thread " + threadName + " exiting."); }

public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } }

public class TestThread {

public static void main(String args[]) { PrintDemo PD = new PrintDemo();

  </span><span class="typ">ThreadDemo</span><span class="pln"> T1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ThreadDemo</span><span class="pun">(</span><span class="pln"> </span><span class="str">"Thread - 1 "</span><span class="pun">,</span><span class="pln"> PD </span><span class="pun">);</span><span class="pln">
  </span><span class="typ">ThreadDemo</span><span class="pln"> T2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ThreadDemo</span><span class="pun">(</span><span class="pln"> </span><span class="str">"Thread - 2 "</span><span class="pun">,</span><span class="pln"> PD </span><span class="pun">);</span><span class="pln">

  T1</span><span class="pun">.</span><span class="pln">start</span><span class="pun">();</span><span class="pln">
  T2</span><span class="pun">.</span><span class="pln">start</span><span class="pun">();</span><span class="pln">

  </span><span class="com">//wait for threads to end</span><span class="pln">
  </span><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
     T1</span><span class="pun">.</span><span class="kwd">join</span><span class="pun">();</span><span class="pln">
     T2</span><span class="pun">.</span><span class="kwd">join</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="typ">Exception</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
     </span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Interrupted"</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

} }

每次您运行该程序时,都会产生相同的输出-

Starting Thread - 1
Starting Thread - 2
Counter   ---   5
Counter   ---   4
Counter   ---   3
Counter   ---   2
Counter   ---   1
Thread Thread - 1  exiting.
Counter   ---   5
Counter   ---   4
Counter   ---   3
Counter   ---   2
Counter   ---   1
Thread Thread - 2  exiting.

参考链接

www.learnfk.com/java/java-t…