Tại sao không dùng nhiều processes , sao không là multiprocessing mà lại cần đến multithreading ?
Trang 1 trong tổng số 1 trang
Tại sao không dùng nhiều processes , sao không là multiprocessing mà lại cần đến multithreading ?
Câu trả lời đơn giản nhất là: Việc tạo ra và quản lý các process đòi hỏi nhiều tài nguyên của hệ thống (cả ram và CPU) nhiều hơn rất nhiều so với việc tạo ra một thread. Trong khi đó có thể chỉ cần tạo ra một thread để thực hiện song song một công việc hết sức đơn giản cùng với một công việc chính.
Viết một ứng dụng Java trên bất kỳ nền tảng nào. Khi ứng dụng ,ta chạy thì thực sự đã có một bản sao của JVM khởi động và ứng dụng của ta là một thread nếu ta không dùng multithreading hoặc là nhiều threads nếu tadùng multithreading.
Tạo một threadNhư đã nói, mỗi khi chạy một ứng dụng trong java thì đã có một thread. Đây là thread chính, nó thực thi các dóng lệnh trong method : public static void main . Đây là một điểm nhập bắt buộc cho mọi ứng dụng độc lập.
Để tạo ra một thread khác ngoài thread chính trên, Java cung cấp cho chúng ta hai cách :
- Tạo ra một lớp con của lớp Thread (java.lang.Thread)
- Tạo ra một lớp hiện thực interface Runnable
Chúng ta sẽ tìm hiểu lần lược hai cách trên.
Tạo một lớp con của lớp java.lang.Thread
Bạn khai báo như sau :
class A extends Thread {
public void run() {
... // code for the new thread to execute
}
}
...
A a = new A(); // create the thread object
a.start(); // start the new thread executing
...
Với cách này các dòng lệnh sẽ được đặt trong method run. Method này được override method nguyên thuỷ của lớp Thread.
Sau đó ta sẽ tạo ra một đối tượng từ lớp của ta.
Gọi phương thức start từ đối tượng đó. Lúc này thread của ta chính thức được tạo ra và phương thức start sẽ tự gọi method run của tavà thực thi các dòng lệnh mà đã đặc tả.
Chú ý rằng: method start là method của hệ thống, nó có nhiệu vụ cấp phát bộ nhớ, tạo ra một thread và gọi hàm run của ta. Vì thế không nên override phương thức này. Điều này có thể dẫn đến ko tạo được thread.
Hiện thực interface Runnable
Khai báo như sau:
class B extends … implements Runnable {
public void run() {
... // code for the new thread to execute
}
}
...
B b = new B(); // create the Runnable object
Thread t = new Thread(b); // create a thread object
t.start(); // start the new thread
...
Cũng giống như cách trên, dòng lệnh đặt trong method run (có thể gọi đến các phương thức khác, nhưng phải bắt đầu trong phương thức này)
Sau đó tạo một đối tượng B từ lớp đã hiện thực interface Runnable, tạo thêm một đối tượng t của lớp Thread với thông số cho constructor là đối tượng B.
Sau đó khi gọi phương thức t.start() thì chính thức thread được tạo ra và phương thức run sẽ được triệu gọi một cách tự động.
Bạn sẽ hỏi tại cách thứ hai vẫn phải tạo ra một đối tượng Thread. Vậy tại sao lại đưa ra hai cách hiện thực làm gì ?
Câu trả lời là :
- Bản thân ngôn ngữ Java không hỗ trợ đa thừa kế . Bạn chỉ có thể extends từ một lớp duy nhất. Nhưng bạn lại có thể implements cùng lúc nhiều interface. Khi mà lớp của ta đã [extends] một lớp nào đó rồi (vd : Applet), thì chỉ có thể implements Runnable để tạo ra Thread.
- Việc extends lớp Thread có thể dẫn đến rủi ro là bạn override các method start, stop, ... thì có thể làm cho việc tạo thread là không thể.
Một lời khuyên là: nên tạo ra một lớp hiện thực interface Runnable (cách thứ hai) khi muốn tạo ra một Thread. Chương trình sẽ trong sáng và dễ tìm lỗi hơn.
-------------------------------
Việc đồng bộ hóa một method là cách tốt nhất để hạn chế việc sử dụng một method tại một thời điểm. Tuy nhiên sẽ có những trường hợp mà bạn không thể đồng bộ hóa một method, chẳng hạn như khi bạn sử dụng một class được cung cấp bởi bên thứ ba. Trong những trường hợp như thế, bạn không được phép truy cập vào định nghĩa lớp, sẽ ngăn bạn sử dụng từ khóa synchronized.
Sử dụng phát biểu được đồng bộ hoá
Một cách khác để sử dụng từ khóa synchronized là sử dụng phát biểu được đồng bộ hóa. Một phát biểu được đồng bộ hóa chứa một block được đồng bộ hóa , mà bên trong đó đặt những đối tượng và những method được đồng bộ hóa. Gọi các method chứa block được đồng bộ hóa xảy ra khi một thread có được monitor của đối tượng.
Mặc dù bạn có thể gọi những method bên trong một block được đồng bộ hóa, việc công bố method phải được thực hiện bên ngoài một block được đồng bộ hóa.
Ví dụ dưới đây chỉ cách làm thế nào để sử dụng một phát biểu được đồng bộ hóa. Ví dụ này cơ bản cũng giống ví dụ trước, tuy nhiên phát biểu được đồng bộ hóa được sử dụng thay vì từ khóa synchronized. Phát biểu này được đặt trong method run() của class MyThread. Phát biểu được đồng bộ hóa sẽ đồng bộ hóa instance của class Parentheses và vì thế ngăn hai thread sử dụng method display() cùng một lúc.
class Parentheses {
void display(String s) {
System.out.print (”(” + s);
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
System.out.println (”Interrupted”);
}
System.out.println(”)”);
}
}
class MyThread implements Runnable {
String s1;
Parentheses p1;
Thread t;
public MyThread (Parentheses p2, String s2) {
p1= p2;
s1= s2;
t = new Thread(this);
t.start();
}
public void run() {
synchronized(p1){
p1.display(s1);
}
}
}
class Demo{
public static void main (String args[]) {
Parentheses p3 = new Parentheses();
MyThread name1 = new MyThread(p3, “Bob”);
MyThread name2 = new MyThread(p3, “Mary”);
try {
name1.t.join();
name2.t.join();
} catch (InterruptedException e ) {
System.out.println( “Interrupted”);
}
}
}
Ở đây, method display() không sử dụng từ khóa synchronized. Thay vào đó, phát biểu được đồng bộ hóa được sử dụng bên trong method run(). Điều này cho kết quả giống với ví dụ trước bởi vì một thread chờ một khoảng thời gian để thread còn lại kết thúc trước khi tiếp tục xử lý.
Viết một ứng dụng Java trên bất kỳ nền tảng nào. Khi ứng dụng ,ta chạy thì thực sự đã có một bản sao của JVM khởi động và ứng dụng của ta là một thread nếu ta không dùng multithreading hoặc là nhiều threads nếu tadùng multithreading.
Tạo một threadNhư đã nói, mỗi khi chạy một ứng dụng trong java thì đã có một thread. Đây là thread chính, nó thực thi các dóng lệnh trong method : public static void main . Đây là một điểm nhập bắt buộc cho mọi ứng dụng độc lập.
Để tạo ra một thread khác ngoài thread chính trên, Java cung cấp cho chúng ta hai cách :
- Tạo ra một lớp con của lớp Thread (java.lang.Thread)
- Tạo ra một lớp hiện thực interface Runnable
Chúng ta sẽ tìm hiểu lần lược hai cách trên.
Tạo một lớp con của lớp java.lang.Thread
Bạn khai báo như sau :
class A extends Thread {
public void run() {
... // code for the new thread to execute
}
}
...
A a = new A(); // create the thread object
a.start(); // start the new thread executing
...
Với cách này các dòng lệnh sẽ được đặt trong method run. Method này được override method nguyên thuỷ của lớp Thread.
Sau đó ta sẽ tạo ra một đối tượng từ lớp của ta.
Gọi phương thức start từ đối tượng đó. Lúc này thread của ta chính thức được tạo ra và phương thức start sẽ tự gọi method run của tavà thực thi các dòng lệnh mà đã đặc tả.
Chú ý rằng: method start là method của hệ thống, nó có nhiệu vụ cấp phát bộ nhớ, tạo ra một thread và gọi hàm run của ta. Vì thế không nên override phương thức này. Điều này có thể dẫn đến ko tạo được thread.
Hiện thực interface Runnable
Khai báo như sau:
class B extends … implements Runnable {
public void run() {
... // code for the new thread to execute
}
}
...
B b = new B(); // create the Runnable object
Thread t = new Thread(b); // create a thread object
t.start(); // start the new thread
...
Cũng giống như cách trên, dòng lệnh đặt trong method run (có thể gọi đến các phương thức khác, nhưng phải bắt đầu trong phương thức này)
Sau đó tạo một đối tượng B từ lớp đã hiện thực interface Runnable, tạo thêm một đối tượng t của lớp Thread với thông số cho constructor là đối tượng B.
Sau đó khi gọi phương thức t.start() thì chính thức thread được tạo ra và phương thức run sẽ được triệu gọi một cách tự động.
Bạn sẽ hỏi tại cách thứ hai vẫn phải tạo ra một đối tượng Thread. Vậy tại sao lại đưa ra hai cách hiện thực làm gì ?
Câu trả lời là :
- Bản thân ngôn ngữ Java không hỗ trợ đa thừa kế . Bạn chỉ có thể extends từ một lớp duy nhất. Nhưng bạn lại có thể implements cùng lúc nhiều interface. Khi mà lớp của ta đã [extends] một lớp nào đó rồi (vd : Applet), thì chỉ có thể implements Runnable để tạo ra Thread.
- Việc extends lớp Thread có thể dẫn đến rủi ro là bạn override các method start, stop, ... thì có thể làm cho việc tạo thread là không thể.
Một lời khuyên là: nên tạo ra một lớp hiện thực interface Runnable (cách thứ hai) khi muốn tạo ra một Thread. Chương trình sẽ trong sáng và dễ tìm lỗi hơn.
-------------------------------
Việc đồng bộ hóa một method là cách tốt nhất để hạn chế việc sử dụng một method tại một thời điểm. Tuy nhiên sẽ có những trường hợp mà bạn không thể đồng bộ hóa một method, chẳng hạn như khi bạn sử dụng một class được cung cấp bởi bên thứ ba. Trong những trường hợp như thế, bạn không được phép truy cập vào định nghĩa lớp, sẽ ngăn bạn sử dụng từ khóa synchronized.
Sử dụng phát biểu được đồng bộ hoá
Một cách khác để sử dụng từ khóa synchronized là sử dụng phát biểu được đồng bộ hóa. Một phát biểu được đồng bộ hóa chứa một block được đồng bộ hóa , mà bên trong đó đặt những đối tượng và những method được đồng bộ hóa. Gọi các method chứa block được đồng bộ hóa xảy ra khi một thread có được monitor của đối tượng.
Mặc dù bạn có thể gọi những method bên trong một block được đồng bộ hóa, việc công bố method phải được thực hiện bên ngoài một block được đồng bộ hóa.
Ví dụ dưới đây chỉ cách làm thế nào để sử dụng một phát biểu được đồng bộ hóa. Ví dụ này cơ bản cũng giống ví dụ trước, tuy nhiên phát biểu được đồng bộ hóa được sử dụng thay vì từ khóa synchronized. Phát biểu này được đặt trong method run() của class MyThread. Phát biểu được đồng bộ hóa sẽ đồng bộ hóa instance của class Parentheses và vì thế ngăn hai thread sử dụng method display() cùng một lúc.
class Parentheses {
void display(String s) {
System.out.print (”(” + s);
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
System.out.println (”Interrupted”);
}
System.out.println(”)”);
}
}
class MyThread implements Runnable {
String s1;
Parentheses p1;
Thread t;
public MyThread (Parentheses p2, String s2) {
p1= p2;
s1= s2;
t = new Thread(this);
t.start();
}
public void run() {
synchronized(p1){
p1.display(s1);
}
}
}
class Demo{
public static void main (String args[]) {
Parentheses p3 = new Parentheses();
MyThread name1 = new MyThread(p3, “Bob”);
MyThread name2 = new MyThread(p3, “Mary”);
try {
name1.t.join();
name2.t.join();
} catch (InterruptedException e ) {
System.out.println( “Interrupted”);
}
}
}
Ở đây, method display() không sử dụng từ khóa synchronized. Thay vào đó, phát biểu được đồng bộ hóa được sử dụng bên trong method run(). Điều này cho kết quả giống với ví dụ trước bởi vì một thread chờ một khoảng thời gian để thread còn lại kết thúc trước khi tiếp tục xử lý.
Phamvantoan(I22A)- Tổng số bài gửi : 13
Join date : 13/03/2013
Age : 34
Đến từ : Thanh Hóa
Similar topics
» Thảo luận Bài 8
» Nhiều kỹ thuật từ lâu không dùng nữa nhưng vẫn phải học. Tại sao ?
» Thảo luận Bài 8
» Thảo luận Bài 8
» Thảo luận Bài 8
» Nhiều kỹ thuật từ lâu không dùng nữa nhưng vẫn phải học. Tại sao ?
» Thảo luận Bài 8
» Thảo luận Bài 8
» Thảo luận Bài 8
Trang 1 trong tổng số 1 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết