Đồng bộ hóa trong Java: Cái gì, Cách thức và Tại sao?



Bài viết này về Đồng bộ hóa trong Java sẽ giúp bạn hướng dẫn cách tìm hiểu về đồng bộ hóa các chương trình đa luồng.

Các chương trình đa luồng có thể thường xuyên xuất hiện trong trường hợp nhiều cố gắng truy cập cùng một nguồn tài nguyên tạo ra kết quả gian lận và đáng kinh ngạc. Điều này có thể được giải quyết bằng cách sử dụng đồng bộ hóa trong Java. Chỉ một luồng cụ thể duy nhất có thể truy cập tài nguyên vào một mục đích thời gian nhất định. Bài viết này sẽ giúp bạn làm quen với chiến lược đồng bộ hóa.

Tôi sẽ thảo luận các chủ đề theo thứ tự sau:





Bắt đầu nào!

Tại sao sử dụng Đồng bộ hóa trong Java?



Nếu bạn bắt đầu với ít nhất hai luồng bên trong một chương trình, có thể xảy ra trường hợp nhiều luồng cố gắng truy cập cùng một tài nguyên. Nó thậm chí có thể tạo ra một kết quả không mong muốn vì các vấn đề đồng thời.

Cú pháp :

đồng bộ hóa (objectidentifier) ​​{// Truy cập các biến được chia sẻ và các tài nguyên được chia sẻ khác}

Ví dụ, cố gắng viết trong một tệp tương đương. Điều này có thể làm hỏng dữ liệu vì một trong các chuỗi có thể ghi đè dữ liệu hoặc khi một chuỗi đang mởcùng một lúc, một chuỗi khác có thể đang đóng cùng một tệp.Cần phải đồng bộ hóa hành động của nhiều luồng. Điều này có thể được thực hiện bằng cách sử dụng một khái niệm được gọi là M người giám sát .



  • Mỗi được liên kết với màn hình mà một luồng có thể khóa hoặc mở khóa.
  • Mỗi lần chỉ có một luồng có thể giữ khóa trên màn hình.
  • Java ngôn ngữ lập trình cung cấp một cách rất tiện dụng để tạo các luồng và đồng bộ hóa tác vụ của chúng bằng cách sử dụng Đồng bộ hóa các khối.
  • Nó cũng giữ các tài nguyên được chia sẻ trong khối cụ thể này.

Các khối được đồng bộ hóa trong Java được đánh dấu bằng Đồng bộ hóa từ khóa. Khối này trong Java được đồng bộ hóa trên một số đối tượng.Tất cả các khối được đồng bộ hóa trên cùng một đối tượng chỉ có thể có một luồng thực thi bên trong chúng tại một thời điểm. Tất cả các luồng khác cố gắng vào khối được đồng bộ hóa sẽ bị chặn cho đến khi luồng bên trong khối được đồng bộ hóa thoát khỏi khối.

Các loại đồng bộ hóa

Về cơ bản có hai loại đồng bộ hóa có sẵn. Họ đang:

  1. Đồng bộ hóa quy trình: Việc thực thi đồng thời nhiều luồng hoặc quy trình để đạt được trạng thái mà chúng cam kết với một chuỗi hành động nhất định.
  2. Đồng bộ hóa chuỗi: Những lúc có nhiều hơn một chuỗicố gắng truy cập tài nguyên được chia sẻ, bạn cần đảm bảo rằng tài nguyên đó sẽ chỉ được sử dụng bởi một chuỗi tạimột thời gian.

Đừng đi vào chi tiết của những loại này và cố gắng hiểu những gì là khóa trong .

Khóa trong Java

Như tôi đã đề cập trước đó, Đồng bộ hóa được xây dựng xung quanh một thực thể nội bộ được gọi là Khóa hoặc là giám sát . Mỗi và mọi đối tượng đều có một khóa liên kết với nó. Vì vậy, một chuỗi cần truy cập nhất quán vào các trường của đối tượng cần có được khóa của đối tượng trước khi truy cập chúng và sau đó nhả khóa khi công việc hoàn tất.

Từ Java 5, gói java.util.concurrent.locks chứa nhiều triển khai khóa.

đầu bếp vs rối vs muối

Đây là cách một ổ khóa trông như thế nào:

public class Lock {private boolean isLocked = false public sync void lock () ném InterruptException {while (isLocked) {wait ()} isLocked = true} public sync void unlock () {isLocked = false notification ()}}

Phương thức lock () khóa cá thể Lock để tất cả các luồng gọi lock () bị chặn cho đến khi thực thi unlock ().

Đa luồng mà không cần đồng bộ hóa

Đây là một ví dụ đơn giản in giá trị bộ đếm theo một chuỗi và mỗi khi chúng tôi chạy nó, nó sẽ tạo ra một kết quả khác dựa trên tính khả dụng của CPU đối với một luồng. Kiểm tra này ra!

class Multithread {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 Thread extends Multithread { private Thread t private String threadName Multithread MT Thread( String name, Multithread mt) { threadName = name MT= mt } public void run() { MT.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[]) { Multithread MT = new Multithread() Thread t = new Thread( 'Thread - 1 ', MT) Thread t1 = new Thread( 'Thread - 2 ', MT) t.start() t1.start() // wait for threads to end try { t.join() t1.join() } catch ( Exception e) { System.out.println('Interrupted') } } }

Kết quả của chương trình ở trên là:

Đầu ra- Đồng bộ hóa trong Java- Edureka

Đa luồng với đồng bộ hóa

Đây là ví dụ tương tự như trên nhưng nó in giá trị bộ đếm trong chuỗi. Mỗi khi chúng tôi chạy nó, nó sẽ tạo ra cùng một kết quả.

class Multithread {public void printCount () {try {for (int i = 5 i> 0 i--) {System.out.println ('Counter ---' + i)}} catch (Exception e) {System. out.println ('Luồng bị gián đoạn.')}}} class Luồng mở rộng Đa luồng {private Thread t private String threadName Multithread MT Thread (String name, Multithread mt) {threadName = name MT = mt} public void run () {sync ( MT) {MT.printCount ()} System.out.println ('Thread' + threadName + 'exiting.')} Public void start () {System.out.println ('Start' + threadName) if (t == null) {t = new Thread (this, threadName) t.start ()}}} public class TestThread {public static void main (String args []) {Multithread MT = new Multithread () Thread T = new Thread ('Thread - 1 ', MT) Thread T1 = new Thread (' Thread - 2 ', MT) T.start () T1.start () // đợi luồng kết thúc thử {T.join () T1.join ()} bắt (Ngoại lệ e) {System.out.println ('Bị gián đoạn')}}}

Đầu ra được mô tả dưới đây:

c ++ sắp xếp mảng các int

Từ khoá được Đồng bộ hoá

từ khóa được đồng bộ hóa đánh dấu một khối hoặc một phương pháp một phần quan trọng. Phần quan trọng là nơi chỉ có một luồng đang thực thi tại một thời điểm và luồng giữ khóa cho phần được đồng bộ hóa. Điều này đồng bộ từ khóa giúp bằng văn bản đồng thời các phần của bất kỳ ứng dụng nào. Nó cũng bảo vệ các tài nguyên được chia sẻ trong khối.

Từ khóa được đồng bộ hóa có thể được sử dụng với:

Hãy thảo luận về khối mã.

Từ khoá được Đồng bộ hoá: Một khối mã

Cú pháp

Cú pháp chung để viết một khối được đồng bộ hóa là:

đồng bộ hóa (lockObject) {// câu lệnh được đồng bộ hóa}

Khi một luồng muốn thực thi các câu lệnh được đồng bộ hóa bên trong khối, nó phải có được khóa trên màn hình của lockObject. Tại một thời điểm chỉ có một luồng có thể thu được màn hình của đối tượng khóa. Vì vậy, tất cả các luồng khác phải đợi cho đến khi luồng đang thực thi có được khóa và kết thúc quá trình thực thi của nó.
Theo cách này, đồng bộ từ khóa đảm bảo rằng chỉ một luồng sẽ thực thi các câu lệnh khối được đồng bộ hóa tại một thời điểm và do đó ngăn nhiều luồng làm hỏng dữ liệu được chia sẻ có bên trong khối.

Ghi chú :

  • Nếu một chuỗi được đặt ở chế độ ngủ (sử dụng ngủ() phương pháp) thì nó không phát hành khóa. Trong thời gian ngủ này, sẽ không có luồng nào thực thi các câu lệnh khối được đồng bộ hóa.
  • Đồng bộ hóa Java sẽ ném NullPointerException nếu đối tượng khóa được sử dụng trong ‘ đồng bộ hóa (khóa) ‘Là null.

Bây giờ, chúng ta hãy thảo luận về phương pháp.

Từ khoá được Đồng bộ hoá: Một phương pháp

Cú pháp

Cú pháp chung để viết một phương pháp đồng bộ Là:

phương thức được đồng bộ hóa (tham số) {// mã được đồng bộ hóa}

Đây lockObject chỉ là một tham chiếu đến một đối tượng có khóa được liên kết với màn hình đại diện cho các câu lệnh được đồng bộ hóa.

Tương tự như khối được đồng bộ hóa, một luồng phải có được khóa trên đối tượng giám sát được kết nối với phương thức được đồng bộ hóa. Trong trường hợp phương thức được đồng bộ hóa, đối tượng khóa là:

  • Đối tượng ‘.class’ - nếu phương pháp đã cho là tĩnh .
  • Đối tượng ‘this’ - nếu phương pháp là không tĩnh . ‘This’ là tham chiếu đến đối tượng hiện tại mà phương thức được đồng bộ hóa được gọi.

Từ khóa đồng bộ hóa Java là gia nhập lại trong thiên nhiên. Nó có nghĩa là nếu một phương thức được đồng bộ hóa gọi một phương thức được đồng bộ hóa khác yêu cầu cùng một khóa, thì luồng hiện tại đang giữ khóa có thể nhập vào phương thức đó mà không cần lấy khóa.

Chúng ta hãy chuyển sang chủ đề cuối cùng của bài viết này và chỉ ra sự khác biệt chính giữa từ khóa được đồng bộ hóa và khối đồng bộ hóa.

Sự khác biệt giữa từ khóa được đồng bộ hóa và khối được đồng bộ hóa

  • Khi bạn sử dụng từ khóa được đồng bộ hóa với phương pháp , nó có được một khóa đối tượng cho toàn bộ phương thức. Điều này có nghĩa là không có luồng nào khác có thể sử dụng bất kỳ phương thức đồng bộ nào cho đến khi luồng hiện tại được gọi kết thúc quá trình thực thi.
  • Đồng bộ hóa khối có được một khóa đối tượng chỉ giữa các dấu ngoặc đơn sau khi từ khóa được đồng bộ hóa được chỉ định. Điều này có nghĩa là không một luồng nào khác có thể có được một khóa trên đối tượng đã bị khóa cho đến khi khối đó thoát ra. Nhưng các luồng khác sẽ có thể truy cập phần còn lại của mã có trong phương thức.

Điều này đưa chúng ta đến phần cuối của bài viết này, nơi chúng ta đã thảo luận về cách chính xác của Đồng bộ hóa trong Java hoạt động. Hy vọng bạn rõ ràng với tất cả những gì đã được chia sẻ với bạn trong hướng dẫn này.

Kiểm tra của Edureka, một công ty học trực tuyến đáng tin cậy với mạng lưới hơn 250.000 người học hài lòng trải dài trên toàn cầu. Chúng tôi ở đây để giúp bạn từng bước trên hành trình của bạn, để trở thành một người ngoài câu hỏi phỏng vấn java này, chúng tôi còn đưa ra một chương trình giảng dạy được thiết kế cho sinh viên và các chuyên gia muốn trở thành một Nhà phát triển Java.

Có một câu hỏi cho chúng tôi? Vui lòng đề cập đến nó trong phần nhận xét của 'Đồng bộ hóa trong Java ' và chúng tôi sẽ liên hệ lại với bạn trong thời gian sớm nhất.