Java 简明教程

Java - Static Synchronization

Synchronization 是一种建立多个试图访问共享资源的线程间协作的方式。对于可靠的线程交互是必需的,并且使用“synchronized”关键字来完成此操作。在这里,线程是一个大型操作中的小的子进程。在本文中,我们将学习静态同步,以及它们如何管理线程,使其能够高效地工作。

Synchronization is a way that establishes cooperation between multiple threads trying to access shared resources. It is necessary for reliable thread interaction and is done using the 'synchronized' keyword. Here, threads are small sub processes of a big operation. In this article, we are going to learn static synchronization and how they manage threads so that they can work efficiently.

Multithreading

Multithreading 是一种 feature of Java programming language,使我们能够同时执行多个操作。其中,操作被分成多个称为线程的小部分。每个线程执行一个独立的任务,而不影响其他线程的性能。多线程的主要优点是对资源(例如 CPU)进行了最佳使用,并且它加快了分配的操作的执行时间。

Multithreading is a feature of Java programming language that allows us to perform multiple operations simultaneously. In it, the operation gets divided into multiple smaller parts called a thread. Each thread performs one independent task without affecting the other thread’s performance. The main benefit of multithreading is the optimal use of resources like CPU and it boosts the execution time of allocated operations.

Synchronization

线程是以异步方式执行的,因此无法预测它们将如何交互。有时,多个线程可能尝试访问单个资源,然后会发成问题,因为它可能会创建分配的错误任务结果。这时,同步就会发挥作用,并确保一个线程一次只能访问给定的资源。这是因为存在守护同步区域的锁对象。当一个线程进入该区域时,锁将被分配给它,而且在执行它的任务后它将释放锁。直到资源占用,其他线程都在队列中等待它们的轮次。

The threads are executed in an asynchronous manner therefore, it is impossible to predict how they are going to interact. Sometimes, several threads may try to access a single resource, then a problem arises because it might create a faulty result of the allocated task. At this time, Synchronization comes into the picture and ensures that a single thread can access the given resource at one time. This is possible because of the lock object that guards the synchronized region. When a thread enters that region, the lock gets assigned to it and it releases the lock after executing its task. Till the resources are busy other threads wait in a queue for their turn.

Static Synchronization in Java

当我们使用这种同步类型时,如果一个线程在静态同步区域,则尝试访问此区域的所有其他线程将被阻塞。由于静态方法属于类,因此静态同步应用类级别锁。

When we use this type of synchronization then, if a thread is in the static synchronized region, all other threads trying to access this region will be blocked. Since static methods belong to the class therefore, static synchronization applies class level lock.

Syntax of Static Synchronization

static synchronized returnType nameOfMethod( Type parameters) {
	// code
}

这里,returnType 可能为空或任何原始数据类型。parameters 包含变量名称,后跟数据类型。

Here returnType may be void or any primitive data type. parameters contains name of the variable followed by datatype.

Multithreading Without Static Synchronization

这是一个简单的示例,它可能并不会按顺序打印 counter 的值,而且每次运行都会基于线程对 CPU 的可用性产生不同的结果。

Here is a simple example which may or may not print counter value in sequence and every time we run it, it produces a different result based on CPU availability to a thread.

Example of Multithreading Without Static Synchronization

package com.tutorialspoint;

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

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

   ThreadDemo( String name) {
      threadName = name;
   }

   public void run() {
      PrintDemo.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[]) {
      ThreadDemo t1 = new ThreadDemo( "Thread - 1 " );
      ThreadDemo t2 = new ThreadDemo( "Thread - 2 " );

      t1.start();
      t2.start();

      // wait for threads to end
         try {
         t1.join();
         t2.join();
      } catch ( Exception e) {
         System.out.println("Interrupted");
      }
   }
}

每次运行该程序都会产生不同的结果——

This produces a different result every time you run this program −

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

Multithreading With Static Synchronization

这是一个在每次运行时都会按顺序打印 counter 值的示例,而且每次都产生相同的结果。这次,我们在一个方法上放了 synchronized 关键字,因此在方法执行期间,整个方法会按照对象锁定。

Here is the same example which prints counter value in sequence and every time we run it, it produces the same result. W’ve put synchronized keyword over a method this time so that complete method is locked as per the object during method execution.

Example of Multithreading With Static Synchronization

package com.tutorialspoint;

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

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

   ThreadDemo( String name) {
      threadName = name;
   }

   public void run() {
      PrintDemo.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[]) {
      ThreadDemo t1 = new ThreadDemo( "Thread - 1 " );
      ThreadDemo t2 = new ThreadDemo( "Thread - 2 " );

      t1.start();
      t2.start();

      // wait for threads to end
         try {
         t1.join();
         t2.join();
      } catch ( Exception e) {
         System.out.println("Interrupted");
      }
   }
}

每次运行该程序都会产生以下结果——

This produces following result every time you run this program −

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.