Thread Synchronization trong Java

Thread Synchronization trong Java

Khi chúng ta bắt đầu hai hoặc nhiều thread bên trong một chương trình, có thể có tình huống khi nhiều thread cố gắng truy cập cùng một nguồn và cuỗi cùng chúng có thể đưa ra kết quả không như dự kiến do sự xảy ra đồng thời. Ví dụ, nếu nhiều thread cố gắng ghi vào trong cùng một file, thì khi đó chúng có thể làm ngắt dữ liệu, bởi vì một trong các thread có thể override dữ liệu hoặc trong khi một thread mở file cùng thời điểm với thread khác đang đóng file này.

Vì thế, nó là cần thiết để đồng bộ hoạt đồng của nhiều thread và đảm bảo rằng chỉ có một thread có thể truy cập nguồn tại một thời điểm. Điều này được triển khai bởi sử dụng một khái niệm được gọi là monitors. Mỗi đối tượng trong Java được xem như là một monitor, mà một thread có thể lock hoặc unlock. Chỉ có một thread tại một thời điểm có thể giữ một lock trên một monitor.

Để hiểu sâu hơn các khái niệm được trình bày trong chương này, mời bạn tham khảo loạt bài: Ví dụ về Thread trong Java.

Ngôn ngữ lập trình Java cung cấp một cách rất thuận tiện để tạo các thread và đồng bộ hóa tác vụ của chúng bởi sử dụng các khối synchronized. Bạn giữ nguồn chia sẻ (shared resource) bên trong block này. Sau đây là form chung của lệnh synchronized trong Java.

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

Tại đây, objectidentifier là một tham chiếu tới một đối tượng, mà có lock liên kết với monitor, mà lệnh synchronized biểu diễn. Bây giờ, chúng ta sẽ xem xét 2 ví dụ, mà sẽ in một bộ đếm (counter) bởi sử dụng 2 thread khác nhau. Khi các thread chưa được synchronized, chúng in giá trị counter mà không liên tục, nhưng khi chúng ta in counter bởi việc đặt bên trong khối synchronized(), thì nó in counter theo dãy liên tục cho cả hai thread.

Ví dụ về đa luồng mà không sử dụng Synchronization trong Java

Ví dụ đơn giản sau có thể hoặc không thể in giá trị counter liên tục và mỗi lần chúng ta chạy nó, nó cho kết quả khác nhau dựa vào tính khả dụng của CPU tới một thread.

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[]) {      PrintDemo PD = new PrintDemo();      ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );
      ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );      T1.start();
      T2.start();      // wait for threads to end
      try {
         T1.join();
         T2.join();
      } catch( Exception e) {
         System.out.println("Interrupted");
      }
   }
}

Quảng cáo

Nó sẽ cho kết quả khác nhau mỗi lần chúng ta chạy chương trình này:

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.

Ví dụ về đa luồng với Synchronization trong Java

Trong ví dụ sau, chúng tôi sử dụng lệnh synchronized trong Java, mà sẽ in giá trị counter liên tục và cho cùng kết quả mỗi lần chúng ta chạy chương trình.

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();      ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );
      ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );      T1.start();
      T2.start();      // wait for threads to end
      try {
         T1.join();
         T2.join();
      } catch( Exception e) {
         System.out.println("Interrupted");
      }
   }
}

Quảng cáo

Nó sẽ cho cùng một kết quả mỗi khi chạy chương trình này:

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.

Đã có app VietJack trên điện thoại, giải bài tập SGK, SBT Soạn văn, Văn mẫu, Thi online, Bài giảng….miễn phí. Tải ngay ứng dụng trên Android và iOS.


Theo dõi chúng tôi miễn phí trên mạng xã hội facebook và youtube:

Các bạn có thể mua thêm khóa học JAVA CORE ONLINE VÀ ỨNG DỤNG cực hay, giúp các bạn vượt qua các dự án trên trường và đi thực tập Java. Khóa học có giá chỉ 300K, nhằm ưu đãi, tạo điều kiện cho sinh viên cho thể mua khóa học.

Nội dung khóa học gồm 16 chuơng và 100 video cực hay, học trực tiếp tại https://www.udemy.com/tu-tin-di-lam-voi-kien-thuc-ve-java-core-toan-tap/
Bạn nào có nhu cầu mua, inbox trực tiếp a Tuyền, cựu sinh viên Bách Khoa K53, fb: https://www.facebook.com/tuyen.vietjack

Loạt bài hướng dẫn của chúng tôi dựa một phần trên nguồn tài liệu của: Tutorialspoint.com

Follow facebook cá nhân Nguyễn Thanh Tuyền https://www.facebook.com/tuyen.vietjack để tiếp tục theo dõi các loạt bài mới nhất về Java,C,C++,Javascript,HTML,Python,Database,Mobile…. mới nhất của chúng tôi.

multithread_trong_java.jsp