Bài 1: Giới thiệu về Thread

Đồng bộ(Concurrency)
Máy tính ngày này cho phép ta sử dụng một lúc nhiều ứng dụng, chẳng hạn như bạn vừa nghe nhạc, vừa đánh văn bản word, vừa download nhạc…Hay thậm chí là một ứng dụng đơn cũng thực hiện nhiều task ở cùng một thời điểm. Ví dụ, trình soạn thảo văn bản word, nó luôn luôn sẵn sàng đáp ứng các sự kiện về keyboard và mouse, nó vừa phải reformat text và cập nhật lại màn hình. Các phần mềm làm những task như vậy gọi là phần mềm đồng bộ.
Java platform cũng được thiế kế hỗ trợ lập trình đồng bộ, với hỗ trợ về ngôn ngữ lập trình Java và các thư viện lớp Java. Từ phiên bản 5.0 trở đi, java platform cũng có các API đồng bộ high-level.

Processes và Thread
Trong lập trình đồng bộ, có 2 đơn vị thực thi cơ bản: tiến trình(process) và luồng(thread). Trong ngôn ngữ lập trình Java, lập trình đồng bộ chủ yếu liên quan đến thread. Tuy nhiên, các tiến trình cũng rất quan trọng.
Các hệ thống máy tính thông thường có nhiều tiến trình và thread hoạt động. Thậm chí điều này cũng đúng trong các hệ thống chỉ có một lõi(core) thực thi duy nhất, và vì thế chỉ có một thread thực sự thực hiện tại bất kỳ thời điểm. Thời gian xử lý cho một lõi duy nhất được chia sẻ giữa các tiến trình và thread thông qua một tính năng của hệ điều hành gọi là thời gian slicing.
Nó ngày càng phổ biến cho các hệ thống máy tính có nhiều bộ xử lý hay bộ vi xử lý với nhiều lõi thực hiện. Điều này giúp tăng cường khả năng để thực hiện đồng thời các tiến trình và thread của hệ thống – thậm chí có thể thực hiện đồng thời trên các hệ thống đơn giản, không có nhiều bộ xử lý lõi hoặc thực hiện.

Các tiến trình(Processes)
Một tiến trình có một môi trường thực thi khép kín. Thông thường, một tiến trình thường có một tập các tài nguyên run-time cơ bản độc quyền, và mỗi tiến trình có bộ nhớ không gian riêng của mình.
Các tiến trình thường được xem như các chương trình hay các ứng dụng. Tuy nhiên, những gì mà người dùng thấy như là một ứng dụng đơn gồm nhiều tiến trình cùng hoạt động. Để tạo thuận lợi trong việc giao tiếp giữa các tiến trình, hầu hết các hệ điều điều hành đều hỗ trợ các tài nguyên Inter Process Communication(IPC), như pipe hay socket. IPC không chỉ được sử dụng để giao tiến giữa các tiến trình trong cùng một hệ thống, mà còn giữa các tiến trình trên các hệ thống khác nhau.
Hầu hết thực thi của máy ảo Java chạy như là một tiến trình đơn. Một ứng dụng Java có thể tạo ra các tiến trình bổ xung bằng cách sử dụng đối tượng ProcessBuilder.
Thread

Đôi khi các thread còn được gọi là các tiến trình lightweight. Cả tiến trình và thread đều cung cấp một môi trường thực thi, nhưng tạo ra một thread mới yêu cầu tài nguyên ít hơn là tạo ra một tiến trình mới.
Các thread tồn tại trong một tiến trình- mỗi tiến trình có tối thiểu một thread. Các thread chia sẽ cùng một tài nguyên của tiến trình, bao gồm bộ nhớ và các file mở. Điều này làm cho giao tiếp hiệu quả nhưng lại tiềm ẩn bên trong nó các vấn đề về xử lý tranh chấp tài nguyên giữa các thread.
MultiThread
Các ngôn ngữ lập trình thông thường  không cho phép người lập trình thực hiện nhiều công việc cùng một lúc. Thay vào đó, cung cấp các điều khiển mà chỉ cho phép người lập trình thực hiện một công việc tại một thời điểm, đó là chỉ cho phép thực hiện công việc tiếp theo sau khi đã hoàn tất công việc trước đó. Java cho phép  người lập trình thưc hiện nhiều công việc thông qua API của nó. Người lập trình có thể tạo Thread thực thi, trong đó mỗi thread được phân chia như là một phần của chương trình và có thể thực thi đồng thời với các Thread khác, điều này được gọi là Multiple Thread.
Hầu hết các hệ điều hành ngày nay đều có nhiều hơn một thread chạy đồng thời tại cùng một thời điểm bên trong một tiến trình. Khi máy ảo Java(JavaVM) chạy trên các hệ điều hành đó, một tiến trình mới cũng được tạo ra. Bên trong tiến trình đó, có nhiều thread có thể được tạo ra.
Thông thường, bạn nghĩ các đoạn mã Java bắt đầu thực thi trong phương thức main() và tiến hành tại một đường dẫn thông qua chương trình. Đây chỉ là một ví dụ về thread đơn. Thread chính được sinh ra bởi JavaVM, mà bắt đầu thực thi với phương thức main, nó thực thi tất cả statement trong phương thức main(), và nó chết khi phương thức main() được hoàn tất.
Một thread thứ hai luôn luôn chạy trong JavaVM, đó là bộ dọn rác(garbage collection), nó dọn dẹp các đối tượng và khôi phục lại bộ nhớ. Vì vậy, khi bạn viết một đoạn mã java đơn giãn là System.out.println(“Xin chào”) thì nó cũng được chạy trên môi trường multithread, đó là main thread và garbage collention thread.
Khi một chương trình Java bào gồm một giao diện người dùng đồ họa(GUI), thì JavaVM tạo ra nhiều thread. Một trong các thread này phụ trách cung cấp các sự kiện GUI cho các phương thức trong chương trình, còn thread khác chịu trách nhiệm về vẽ cửa sổ GUI.
Ví dụ: ta có một chương trình dựa trên GUI, với một thread tính toán đang thực thi các công việc tính toán phức tạp và dài hạn, và trong khi điều này đang diễn ra, người dùng nhấn nút Stop. GUI event thread ngay sau đó sẽ gọi các sự kiện xử lý code tương ứng cho nút nhấn Stop, cho phép thread tính toán kết thúc. Nếu chương trình này chỉ có một thread, thì cả hai không thể thực thi cùng lúc, và sẽ gây ra tình trạng gián đoạn.
Thực thi multithread cũng là một đặc điểm thiết yếu của Java platform. Một ứng dụng đều có tối thiểu một thread-hay nhiều nếu bạn đếm các thread hệ thống làm những việc như quản lý bộ nhớ và xử lý tín hiệu. Tuy nhiên, nếu đứng trên quan điểm của người phát triển ứng dụng, bạn chỉ bắt đầu với một thread, và được gọi là main thread. Và thread này có khả năng tạo ra các thread bổ xung, và sẽ được đề cập trong những phần tiếp theo.

Thread Objects
Mỗi thread được liên kết với một thể hiện của lớp Thread. Có hai chiến lược cơ bản cho việc sử dụng các đối tượng Thread để tạo ra một ứng dụng đồng thời.

  • Điều khiển trực tiếp khi tạo ra thread và quản lý nó, đơn giãn là khởi tạo thread mỗi lúc ứng dụng cần bắt đầu một task không đồng bộ.
  • Quản lý thread trừu tượng từ tài nguyên của ứng dụng, đưa các task của ứng dụng vào một bộ thực thi(executor).

Các bài liên quan:
Tìm hiểu Thread trong JAVA-Phần 2