Sự khác nhau giữa đồng bộ và bất đồng bộ

Sự khác nhau giữa đồng bộ và bất đồng bộ

Sự khác nhau giữa đồng bộ và bất đồng bộ

Đồng bộ vs không đồng bộ

Đồng bộ và không đồng bộ là hai từ lớn có vẻ đáng sợ nhưng khá đơn giản. Đồng bộ đơn giản có nghĩa là tất cả các sự kiện đang diễn ra theo một thứ tự thời gian nhất định có thể dự đoán được. Một sự kiện nào đó sẽ luôn theo sau một sự kiện khác và chúng không thể thay thế cho nhau. Không đồng bộ là trái ngược với đồng bộ. Trong các quy trình không đồng bộ, không có thứ tự thời gian. Một số sự kiện có thể, và thường làm, trao đổi. Một ví dụ đồng bộ tuyệt vời là âm nhạc. Mỗi nhạc cụ tham gia cần phải nhịp nhàng với các nhạc cụ khác nếu không âm nhạc sẽ không đúng. Đối với không đồng bộ, một ví dụ tốt sẽ là lưu lượng truy cập. Xe di chuyển với tốc độ khác nhau và thông thường người ta di chuyển qua người khác.

Trong hầu hết các ứng dụng, hoạt động đồng bộ là điều cần thiết vì có một hoạt động không đồng bộ có nghĩa đen là sự hỗn loạn. Ví dụ về điều này là đường sắt và sân bay. Trong các kịch bản này, điều quan trọng là phải biết xe nào đi trước để tránh va chạm. Thứ tự của mọi thứ được lên kế hoạch cẩn thận để tạo điều kiện cho một dòng chảy trôi chảy và những thay đổi đối với kế hoạch là rất ít và xa.

Mặc dù hoạt động đồng bộ thường được ưa thích, có một số trường hợp không cần thiết. Thậm chí có những trường hợp hoạt động đồng bộ có thể gây bất lợi cho mục tiêu. Một ví dụ trong đó hoạt động đồng bộ không thực sự cần thiết là trong trình duyệt internet. Trước AJAX (Javascript không đồng bộ và XML), hầu hết các trang web cần phải được tải lại toàn bộ để thay đổi thông tin trên một phần nhỏ. Với AJAX, giờ đây có thể cập nhật phần nhất định đó trong khi phần còn lại của trang không bị ảnh hưởng. Điều này có lợi vì một lượng dữ liệu nhỏ hơn cần được truyền đi và người dùng không phải chịu đựng trong suốt quá trình làm mới toàn bộ trang. AJAX không đồng bộ vì các cập nhật trang không còn được đồng bộ hóa.

Trong hoạt động của máy tính, I / O là một lĩnh vực mà hoạt động đồng bộ trở nên bất lợi. Hoạt động đồng bộ trong vấn đề này có nghĩa là bộ xử lý cần chờ dữ liệu được ghi hoặc đọc trước khi có thể tiếp tục. Vấn đề là, các thiết bị I / O như ổ cứng và đặc biệt là ổ đĩa mềm, có bộ phận cơ học, rất chậm. Nếu bộ xử lý cần đợi ổ đĩa kết thúc, nó sẽ lãng phí rất nhiều thời gian. Hoạt động không đồng bộ cho phép bộ xử lý thực hiện những việc khác trong khi chờ đọc / ghi kết thúc và chỉ tiếp tục khi hoạt động đã thành công.

Tóm lược:Phương tiện đồng bộ theo thứ tự thời gian trong khi Không đồng bộ có nghĩa là không có thứ tự thời gianĐồng bộ được ưa thích hơn không đồng bộ trong nhiều ứng dụng trong thế giới thực

Đồng bộ có thể hoạt động kém hơn trong các trường hợp nhất định so với không đồng bộ

Sự khác nhau giữa đồng bộ và bất đồng bộ

Các sự khác biệt chính giữa truyền đồng bộ và không đồng bộ là truyền đồng bộ sử dụng đồng hồ được đồng bộ hóa để truyền dữ liệu trong khi truyền không đồng bộ sử dụng điều khiển luồng thay vì sử dụng đồng hồ được đồng bộ hóa để truyền dữ liệu.

Truyền dữ liệu là quá trình gửi dữ liệu từ máy phát đến máy thu. Có hai loại truyền dữ liệu được gọi là Truyền song song và Truyền nối tiếp. Truyền nối tiếp gửi một bit tại một thời điểm, tuần tự qua kênh truyền thông. Truyền song song gửi nhiều bit qua một số kênh song song cùng một lúc. Truyền đồng bộ và không đồng bộ là hai loại truyền nối tiếp.

Sự khác nhau giữa đồng bộ và bất đồng bộ

NỘI DUNG

1. Tổng quan và sự khác biệt chính2. Truyền đồng bộ là gì3. Truyền không đồng bộ là gì4. So sánh cạnh nhau - Truyền đồng bộ và không đồng bộ ở dạng bảng

5. Tóm tắt

Truyền đồng bộ là gì?

Trong truyền dẫn nối tiếp, có một kênh duy nhất giữa người gửi và người nhận và các bit được xếp hàng tại thiết bị gửi để truyền đi lần lượt từng chuỗi một. Truyền nối tiếp chia thành truyền truyền đồng bộ và không đồng bộ.

Sự khác nhau giữa đồng bộ và bất đồng bộ

Hình 01: Phân loại truyền dữ liệu

Trong truyền này, đồng hồ máy phát và đồng hồ máy thu được đồng bộ hóa, do đó, chúng chạy ở cùng một tốc độ. Nó truyền khối theo từng khối hoặc từng khung một tại một khoảng thời gian cố định. Hơn nữa, nó không có chi phí hoạt động với các bit đầu trang và chân trang bổ sung. Tóm lại, truyền đồng bộ là hiệu quả, đáng tin cậy và cho phép truyền một lượng lớn dữ liệu.

Truyền không đồng bộ là gì?

Truyền không đồng bộ, còn được gọi là truyền bắt đầu / dừng, gửi dữ liệu từ người gửi đến người nhận bằng phương pháp kiểm soát luồng. Nó không sử dụng đồng hồ để đồng bộ hóa dữ liệu giữa nguồn và đích.

Việc truyền này gửi một ký tự hoặc 8 bit mỗi lần. Trước khi truyền từng ký tự, nó sẽ gửi bit bắt đầu. Sau khi gửi ký tự, nó sẽ gửi bit dừng. Với các bit ký tự và các bit start và stop, tổng số bit trong 10 bit. Tóm lại, nó là một phương thức truyền tải đơn giản, nhanh chóng và hiệu quả.

Sự khác biệt giữa truyền dẫn đồng bộ và không đồng bộ là gì?

Truyền đồng bộ là phương thức truyền sử dụng đồng hồ được đồng bộ hóa để đảm bảo cả người gửi và người nhận được đồng bộ hóa để truyền dữ liệu. Truyền không đồng bộ là phương thức truyền gửi dữ liệu bằng cách sử dụng điều khiển luồng để truyền dữ liệu giữa nguồn và đích.
Hiệu quả
Hiệu quả hơn Kém hiệu quả
Phương thức gửi dữ liệu
Gửi khối hoặc khung dữ liệu tại một thời điểm Gửi một byte hoặc ký tự tại một thời điểm
Giá cả
So sánh cao Chi phí thấp
Khoảng thời gian
Sử dụng khoảng thời gian cố định Sử dụng khoảng thời gian tùy ý
Ví dụ
Một số ví dụ về truyền tải đồng bộ là phòng trò chuyện, hội nghị video, cuộc trò chuyện qua điện thoại, v.v.. Email, truyền hình và radio là một vài ví dụ cho việc truyền không đồng bộ.

Tóm tắt - Truyền đồng bộ và không đồng bộ

Thông thường, nhiều dữ liệu truyền trên mỗi đơn vị thời gian trong truyền đồng bộ hơn so với truyền không đồng bộ. Sự khác biệt giữa truyền đồng bộ và không đồng bộ là truyền đồng bộ sử dụng đồng hồ được đồng bộ hóa để truyền dữ liệu trong khi truyền không đồng bộ sử dụng điều khiển luồng thay vì sử dụng đồng hồ được đồng bộ hóa để truyền dữ liệu. Nhìn chung, truyền đồng bộ đáng tin cậy và hiệu quả hơn truyền không đồng bộ.

Tài liệu tham khảo:

1.Wikipedia, Wikimedia Foundation, ngày 22 tháng 4 năm 2018. Có sẵn tại đây  
2.Tutorials Point., Hướng dẫn Điểm, 8 tháng 1 năm 2018. Có sẵn tại đây 

Hình ảnh lịch sự:

1.'Data Transmission'By Department4 - Công việc riêng, (CC BY-SA 4.0) qua Commons Wikimedia

Tài khoản ngân hàng của công ty X có 10 triệu. Tại một thời điểm, giám đốc rút thẻ thanh toán số tiền 5 triệu sau một bữa giao lưu với đối tác. Cùng lúc đó, tại văn phòng, nhân viên tài chính chuyển 7 triệu để mua sắm chuẩn bị cho sự kiện ngày mai. Chuyện gì sẽ xảy ra? Nếu cả hai giao dịch trên đều được thực hiện thì tổng cộng công ty X đã chi hết 12 triệu trong khi tài khoản mình chỉ có 10 triệu. Ngân hàng sẽ chịu lỗ 2 triệu.

Bài toán trên cũng chính là một ví dụ kinh điển mỗi khi chúng ta đề cập đến khía cạnh đối lập nhau là đồng bộ (Synchronized)bất đồng bộ (Unsynchronized). Hai khái niệm đối lập nhau này cũng chính là chủ đề để chúng ta cùng tìm hiểu sâu hơn trong bài viết này.

Lý do phát sinh vấn đề

Nhìn lại bài toán ngân hàng, chúng ta có thể dễ dàng nhận ra được mấu chốt để phát sinh việc công ty X dùng quá số tiền so với tài khoản hiện có chính là việc có 2 giao dịch cùng một thời điểm.

Giả dụ nếu người giám đốc hoàn tất thanh toán tiền vào lúc 12 giờ trưa, người nhân viên tài chính chuyển tiền vào lúc 3 giờ chiều, lúc này tài khoản công ty đã cập nhật còn 5 triệu, thì sẽ không có việc nhầm lẫn gì ở đây. Đa luồng (Multi-thread) cùng truy cập vào một tài nguyên chính là nguyên nhân gây ra sự sai lệch của giả dụ đầu bài.

Do đây không phải là bài chuyên về luồng (Thread) nên mình sẽ chỉ nói về cách mà các luồng gây sai lệch. 

Ví dụ dưới đây sẽ giúp các bạn có cái nhìn rõ ràng hơn. Mình sẽ mô tả lại trường hợp ví dụ một cách tương đối. Bằng cách tạo ra hai luồng khác nhau cùng truy cập vào một tài nguyên, mình liên tục kiểm tra số tiền hiện tại rồi trừ đi một và in ra giá trị còn lại.

public class TestThread { public static void main(String[] args) { count c = new count(); // Tạo 2 thread truy cập vào cùng tài nguyên trong 1 đối tượng Thread t1 = new Thread(new Access("Thread 1", c)); Thread t2 = new Thread(new Access("Thread 2", c)); t1.start(); t2.start(); } } class count { int value = 10; } class Access implements Runnable { String name; count c; public Access(String name, count c) { this.name = name; this.c = c; } //Có thể đặt từ khóa synchronized vào đây để xem kết quả sau khi đồng bộ public [synchronized] void run() { for (int i = 0; i < 3; i++) { System.out.println(name + " " + "index " + i + " before: " + c.value); c.value--; System.out.println(name + " " + "index " + i + " after: " + c.value); } } } ​

Sau khi chạy đoạn code trên, mình nhận được kết quả như sau.

Sự khác nhau giữa đồng bộ và bất đồng bộ

Chúng ta có thể thấy được ở lượt thứ 0 của Thread 2 đã xảy ra lỗi. Giá trị ban đầu vốn là 10, sau khi trừ đi 1 thì lại chỉ còn 8.

Lý do là bởi vì trong thời gian giữa lệnh in ra giá trị ban đầu và lệnh in ra giá trị sau khi trừ của Thread 2 thì Thread 1 đã thực hiện giảm giá trị của biến value.

Việc sử dụng đa luồng giúp cho việc thực thi các hành động diễn ra nhanh hơn bằng cách để các luồng chạy đan xen lẫn nhau. Nhưng cũng chính vì đó mà nếu không cẩn thận, đa luồng sẽ ảnh hưởng đến việc thực thi hành động của luồng khác thông qua các tài nguyên dùng chung như biến value ở chương trình mẫu bên trên.

Để tránh việc gây nhiễu giữa các luồng với nhau, khái niệm đồng bộbất đồng bộ đã ra đời.

Bất đồng bộ cũng tựa như cách mà chương trình mẫu bên trên thực hiện, mặc kệ các luồng thích làm gì thì làm.

Đồng bộ, phiên bản trái ngược với bất đồng bộ, giữ cho giá trị của các tài nguyên dùng chung không bị sai lệch.

Bạn đã từng đi qua trạm thu phí bao giờ chưa? Trong quá trình tham gia giao thông, các phương tiện có thể vượt mặt nhau để đi trước nhưng khi đến trạm thu phí thì các xe phải xếp hàng vượt trạm từng chiếc một. Xong chiếc này thì sẽ đến chiếc khác.

Quy tắc của đồng bộ cũng như vậy, bằng cách gọi từ khóa synchronized, một bộ phận tài nguyên sẽ bị khóa lại chỉ cho phép một luồng sử dụng trong một thời điểm. Khi nào luồng đó thực hiện xong, quyền sử dụng tài nguyên sẽ được giao lại cho luồng khác.

Các kiểu đồng bộ và làm sao để thực hiện chúng?

Việc thực hiện đồng bộ có thể được thực hiện trên đối tượng (đồng bộ phương thức, đồng bộ khối) và trên lớp.

  1. Đồng bộ phương thức khóa một bộ phận tài nguyên thuộc về đối tượng. Trong một thời điểm, chỉ có một luồng có quyền tương tác với phương thức được đánh dấu đồng bộ. Một đối tượng có thể chứa nhiều phương thức khác nhau, không phải tất cả mọi phương thức đều bị đồng bộ. Các phương thức không đồng bộ có thể được truy cập đa luồng như thường.

    class X{ // Phương thức method1 được gọi đồng bộ // Chỉ được truy cập bởi một luồng vào một thời điểm synchronized void method1() { //Thực hiện một đoạn lệnh } // Phương thức method2 không được đồng bộ // Chấp nhận đa luồng void method2() { //Thực hiện một đoạn lệnh } }
  2. Đồng bộ khối về cơ bản giống với đồng bộ phương thức nhưng thay vì đặt nguyên một phương thức vào trạng thái khóa thì chỉ đặt đoạn lệnh nào có khả năng gây sai lệch.

    class Y{ void method(){ //Đoạn lệnh không cần đồng bộ // từ khóa this có tác dụng thông báo đồng bộ dựa trên đối tượng hiện tại synchronized(this){ // Đoạn lệnh cần đồng bộ } //Đoạn lệnh không cần đồng bộ } }
  3. Trong khi đó thì đồng bộ lớp khóa toàn bộ tài nguyên của lớp đó. Tất cả phương thức bên trong đó chỉ có thể được luồng hiện tại sử dụng. Bên dưới sẽ là ví dụ cho cách dùng này.

    public class TestThread { public static void main(String[] args) { MyThread t1 = new MyThread("Thread 1_1", 1); MyThread t2 = new MyThread("Thread 1_2", 10); MyThread t3 = new MyThread("Thread 1_3", 100); t1.start(); t2.start(); t3.start(); } } class Table { synchronized static void print(String name, int n) { for (int i = 1; i <= 5; i++) System.out.println(name + ": " + i * n); } } class MyThread extends Thread { private String name; private int value; public MyThread(String name, int value) { this.name = name; this.value = value; } public void run() { Table.print(name, value); } }
    Sự khác nhau giữa đồng bộ và bất đồng bộ

    Kết quả khi có đồng bộ

    Sự khác nhau giữa đồng bộ và bất đồng bộ

Kết quả khi không đồng bộ

Tạm kết

Hi vọng bài viết này giúp các bạn nhận thức rõ hơn về các khái niệm đồng bộ và bất đồng bộ. Việc sử dụng synchronized thì sẽ giúp yên tâm hơn trong việc dùng đa luồng, miễn là bạn đặt từ khóa ở đúng chỗ :)

Tuy nhiên, mình cũng khẳng định để có thể thông thạo việc sử dụng đồng bộ đối với các tiến trình đa luồng là một việc không phải chỉ bởi xem qua một vài ví dụ là biết hết. Chỉ khi bắt tay vào làm thử và học hỏi thì mới có thể hiểu rõ hơn cách mà các dòng lệnh hoạt động.