Bài giảng Lập trình Java - Chương 4: Lập trình đa luồng trong Java

Lập trình đơn luồng

(Single Threaded Programming)

 Chương trình biên dịch thành mã máy. Khối mã này được CPU

xử lý tuần tự.

 Xử lý đơn luồng  đơn giản, dễ kiểm soát, dễ dàng biết được

lỗi phát sinh ở đâu.

 Thời gian xử lý các câu lệnh khác nhau, nhưng một câu lệnh

chưa thực thi xong thì các câu lệnh khác không được chạy 

không hợp lý.Lập trình đa luồng

(Multi Threaded Programming)

 Nhiều câu lệnh, nhiệm vụ được thực hiện đồng thời,

cùng một không gian bộ nhớ, và các luồng có thể

cho phép chia sẻ các đối tượng dữ liệu để cùng xử lý.Giới thiệu HĐH đa nhiệm

 Hệ điều hành đa nhiệm cổ điển:

 Đơn vị cơ bản sử dụng CPU là process.

 Process là đoạn chương trình độc lập đã được nạp vào bộ nhớ.

 Mỗi process thi hành một ứng dụng riêng.

 Mỗi process có một không gian địa chỉ và một không gian

trạng thái riêng.

 Các process liên lạc với nhau thông qua cơ chế điều phối của

HĐH.

pdf 43 trang kimcuc 4940
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình Java - Chương 4: Lập trình đa luồng trong Java", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Lập trình Java - Chương 4: Lập trình đa luồng trong Java

Bài giảng Lập trình Java - Chương 4: Lập trình đa luồng trong Java
 LẬP TRÌNH 
ĐA LUỒNG (MULTITHREAD) 
TRONG JAVA 
Nội dung 
 Giới thiệu về đơn luồng và đa luồng 
 Tạo và quản lý luồng trong java 
 Sử dụng Thread và Runnable 
 Vòng đời Thread 
 Độ ưu tiên, Đồng bộ hóa 
 Ví dụ minh họa 
Lập trình đơn luồng 
(Single Threaded Programming) 
 Chương trình biên dịch thành mã máy. Khối mã này được CPU 
xử lý tuần tự. 
 Xử lý đơn luồng đơn giản, dễ kiểm soát, dễ dàng biết được 
lỗi phát sinh ở đâu. 
 Thời gian xử lý các câu lệnh khác nhau, nhưng một câu lệnh 
chưa thực thi xong thì các câu lệnh khác không được chạy 
không hợp lý. 
Lập trình đa luồng 
(Multi Threaded Programming) 
 Nhiều câu lệnh, nhiệm vụ được thực hiện đồng thời, 
cùng một không gian bộ nhớ, và các luồng có thể 
cho phép chia sẻ các đối tượng dữ liệu để cùng xử lý. 
Giới thiệu HĐH đa nhiệm 
 Hệ điều hành đa nhiệm cổ điển: 
 Đơn vị cơ bản sử dụng CPU là process. 
 Process là đoạn chương trình độc lập đã được nạp vào bộ nhớ. 
 Mỗi process thi hành một ứng dụng riêng. 
 Mỗi process có một không gian địa chỉ và một không gian 
trạng thái riêng. 
 Các process liên lạc với nhau thông qua cơ chế điều phối của 
HĐH. 
 Hệ điều hành đa nhiệm hiện đại, hỗ trợ thread: 
 Đơn vị cơ bản sử dụng CPU là thread. 
 Thread một đoạn các câu lệnh được thi hành. 
 Mỗi process có một không gian địa chỉ và nhiều thread 
điều khiển. 
 Mỗi thread có bộ đếm chương trình, trạng thái các 
thanh ghi và ngăn xếp riêng. 
Giới thiệu HĐH đa nhiệm 
 Luồng của một quá trình có thể chia sẻ nhau không gian địa 
chỉ : Biến toàn cục, tập tin, chương trình con, . . . 
 Luồng chia sẻ thời gian sử dụng CPU => Luồng cũng có các 
trạng thái: 
 Sẵn sàng (ready), Đang chạy (running), Nghẽn(Block) như 
quá trình. 
 Luồng cung cấp cơ chế tính toán song song trong các ứng 
dụng. 
Giới thiệu luồng 
Main Thread 
Thread A Thread B Thread C 
start start 
start 
Các thread có thể chuyển đổi dữ liệu với nhau 
Chương trình Multithread 
Ứng dụng Multithread 
9 
Printing Thread 
Editing Thread 
Lập trình multithread với Java 
 Cách thực hiện 
 Sử dụng lớp java.lang.Thread 
public class Thread extends Object {  } 
 Sử dụng giao diện java.lang.Runnable 
public interface Runnable { 
 public void run(); // work thread 
} 
+run()
«interface»
Runnable
1
+currentThread() : Thread
+isInterrupted() : bool
+sleep(in millis : long) : long
+yield()
+isAlive()
+join()
+interrupt()
+start()
+stop()
Thread
Trong Java, chúng ta có thể tạo ra các luồng bằng cách 
sử dụng lớp java.lang.Thread. Ngoài ra chúng ta có 
thể tạo ra các thread thông qua interface Runnable. 
Lớp java.lang.Thread 
 Thread trong java là một đối tượng của lớp java.lang.Thread 
 Một chương trình cài đặt thread bằng cách tạo ra các lớp con 
của lớp Thread. 
 Lớp Thread có 3 phương thức cơ bản: 
 public static synchronized void start() : 
 Chuẩn bị mọi thứ cần thiết để thực hiện thread. 
 public void run(): 
 Chứa mã lệnh thực hiện công việc thực sự của thread. 
 run() được gọi một cách tự động bởi start(). 
 public void stop() : kết thúc một thread. 
 Thread kết thúc khi: 
Hoặc tất cả các lệnh trong run() đã được thực thi. 
Hoặc phương thức stop() của luồng được gọi. 
Lớp java.lang.Thread 
Tạo và quản lý thread 
 Khi chương trình Java thực thi hàm main() tức là luồng main 
được thực thi. Luồng này được tạo ra một cách tự động. tại đây: 
 Các luồng con sẽ được tạo ra từ đó 
 Nó là luồng cuối cùng kết thúc việc thực hiện. Trong chốc lát 
luồng chính ngừng thực thi, chương trình bị chấm dứt 
 Luồng có thể được tạo ra bằng 2 cách: 
 Dẫn xuất từ lớp Thread 
 Dẫn xuất từ Runnable. 
Tạo thread sử dụng lớp Thread 
 Cài đặt lớp kế thừa từ lớp Thread và override phương thức run() 
 class MyThread extends Thread 
 { 
 public void run() 
 { 
 // thread body of execution 
 } 
 } 
 Tạo thread: 
 MyThread thr1 = new MyThread(); 
 Thi hành thread: 
 thr1.start(); 
 Tạo và thi hành thread: 
 new MyThread().start(); 
Ví dụ 
class MyThread extends Thread { // the thread 
 public void run() { 
 System.out.println(" this thread is running ... "); 
 } 
} // end class MyThread 
Ví dụ 
class ThreadEx1 { // a program that utilizes the thread 
 public static void main(String [] args ) { 
 MyThread t = new MyThread(); 
 // due to extending the Thread class (above) 
 // I can call start(), and this will call 
 // run(). start() is a method in class Thread. 
 t.start(); 
 } // end main() 
} // end class ThreadEx1 
Tạo thread sử dụng Runnable 
class MyThread implements Runnable { 
 ..... 
 public void run() { 
 // thread body of execution 
 } 
} 
Tạo thread sử dụng Runnable 
 Tạo đối tượng: 
 MyThread myObject = new MyThread(); 
 Tạo thread từ đối tượng: 
 Thread thr1 = new Thread(myObject); 
 Thi hành thread: 
 thr1.start(); 
class MyThread implements Runnable { 
 public void run() { 
 System.out.println(" this thread is running ... "); 
 } 
} // end class MyThread 
Ví dụ 
class ThreadEx2 { 
 public static void main(String [] args ) { 
 Thread t = new Thread(new MyThread()); 
 // due to implementing the Runnable interface 
 // I can call start(), and this will call run(). 
 t.start(); 
 } // end main() 
} // end class ThreadEx2 
Ví dụ 
Threads – Thread States 
 Các trạng thái của thread: 
 New – thread được tạo ra trong bộ nhớ 
 Runnable – thread có thể được thi hành 
 Running – thread đang thi hành 
 Blocked – thread đang bị treo (I/O, etc.) 
 Dead – thread kết thúc 
 Việc chuyển đổi trạng thái thread thực hiện bởi: 
 Thi hành các phương thức trong lớp Thread 
 new(), start(), yield(), sleep(), wait(), notify() 
 Các sự kiện bên ngoài 
 Scheduler, I/O, returning from run() 
Vòng đời của thread 
runnable 
scheduler 
new 
dead 
running blocked 
new start 
terminate 
IO, sleep, 
wait, join 
yield, 
time 
slice 
notify, notifyAll, 
IO complete, 
sleep expired, 
join complete 
Lưu ý 
 Thread chỉ được thi hành sau khi gọi phương thức start() 
 Runnable là interface 
 Có thể hỗ trợ đa kế thừa 
 Thường dùng khi cài đặt giao diện GUI 
 Viết chương trình thi hành song song 3 thread 
class A extends Thread { 
 public void run() { 
 for(int i=1;i<=5;i++) { 
 System.out.println("\t From ThreadA: i= "+i); 
 } 
 System.out.println("Exit from A"); 
 } 
} 
Ví dụ 
class B extends Thread { 
 public void run() { 
 for(int j=1;j<=5;j++) { 
 System.out.println("\t From ThreadB: j= "+j); 
 } 
 System.out.println("Exit from B"); 
 } 
} 
Ví dụ 
class C extends Thread { 
 public void run() { 
 for(int k=1;k<=5;k++) { 
 System.out.println("\t From ThreadC: k= "+k); 
 } 
 System.out.println("Exit from C"); 
 } 
} 
Ví dụ 
class ThreadTest { 
 public static void main(String args[]) { 
 new A().start(); 
 new B().start(); 
 new C().start(); 
 } 
} 
Ví dụ 
Chạy lần thứ 1 
java ThreadTest 
 From ThreadA: i= 1 
 From ThreadA: i= 2 
 From ThreadA: i= 3 
 From ThreadA: i= 4 
 From ThreadA: i= 5 
Exit from A 
 From ThreadC: k= 1 
 From ThreadC: k= 2 
 From ThreadC: k= 3 
 From ThreadC: k= 4 
 From ThreadC: k= 5 
Exit from C 
 From ThreadB: j= 1 
 From ThreadB: j= 2 
 From ThreadB: j= 3 
 From ThreadB: j= 4 
 From ThreadB: j= 5 
Exit from B 
java ThreadTest 
 From ThreadA: i= 1 
 From ThreadA: i= 2 
 From ThreadA: i= 3 
 From ThreadA: i= 4 
 From ThreadA: i= 5 
 From ThreadC: k= 1 
 From ThreadC: k= 2 
 From ThreadC: k= 3 
 From ThreadC: k= 4 
 From ThreadC: k= 5 
Exit from C 
 From ThreadB: j= 1 
 From ThreadB: j= 2 
 From ThreadB: j= 3 
 From ThreadB: j= 4 
 From ThreadB: j= 5 
Exit from B 
Exit from A 
Chạy lần thứ 2 
Độ ưu tiên 
 Trong Java, mỗi thread được gán 1 giá trị để chỉ mức độ ưu tiên 
của thread. Khi thread được tạo ra có độ ưu tiên mặc định 
(NORM_PRIORITY). 
 Sử dụng phương thức setPriority() để thay đổi độ ưu tiên 
của thread: 
 ThreadName.setPriority(intNumber) 
 MIN_PRIORITY = 1 
 NORM_PRIORITY=5 
 MAX_PRIORITY=10 
Ví dụ về thread priority 
class A extends Thread { 
 public void run() { 
 System.out.println("Thread A started"); 
 for(int i=1;i<=4;i++) { 
 System.out.println("\t From ThreadA: i= "+i); 
 } 
 System.out.println("Exit from A"); 
 } 
} 
Ví dụ về thread priority 
class B extends Thread { 
 public void run() { 
 System.out.println("Thread B started"); 
 for(int j=1;j<=4;j++) { 
 System.out.println("\t From ThreadB: j= "+j); 
 } 
 System.out.println("Exit from B"); 
 } 
} 
Ví dụ về thread priority 
class C extends Thread { 
 public void run() { 
 System.out.println("Thread C started"); 
 for(int k=1;k<=4;k++) { 
 System.out.println("\t From ThreadC: k= "+k); 
 } 
 System.out.println("Exit from C"); 
 } 
} 
class ThreadPriority { 
 public static void main(String args[]) { 
 A threadA=new A(); 
 B threadB=new B(); 
 C threadC=new C(); 
 threadC.setPriority(Thread.MAX_PRIORITY); 
 threadB.setPriority(threadA.getPriority()+1); 
 threadA.setPriority(Thread.MIN_PRIORITY); 
 System.out.println("Started Thread A"); 
 threadA.start(); 
 System.out.println("Started Thread B"); 
 threadB.start(); 
 System.out.println("Started Thread C"); 
 threadC.start(); 
 System.out.println("End of main thread"); 
 } 
} 
Ví dụ về thread priority 
Threads – Scheduling 
 Bộ lập lịch 
 Xác định thread nào sẽ thi hành 
 Có thể thực hiện dựa trên độ ưu tiên 
 Là một phần của HĐH hoặc Java Virtual Machine (JVM) 
Thread Scheduling 
 Ví dụ 
 Tạo lớp kế thừa Thread 
 Sử dụng phương thức sleep() 
 Công việc 
 Tạo 4 thread chạy song sọng, mỗi thread sẽ tạm ngưng 
thi hành một khoảng thời gian ngẫu nhiên. 
 Sau khi kết thúc sleeping sẽ in ra tên thread. 
 1 // ThreadTester.java 
 2 // Show multiple threads printing at different intervals. 
 3 
 4 public class ThreadTester { 
 5 public static void main( String args[] ) 
 6 { 
 7 PrintThread thread1, thread2, thread3, thread4; 
 8 
 9 thread1 = new PrintThread( "thread1" ); 
 10 thread2 = new PrintThread( "thread2" ); 
 11 thread3 = new PrintThread( "thread3" ); 
 12 thread4 = new PrintThread( "thread4" ); 
 13 
 14 System.err.println( "\nStarting threads" ); 
 15 
 16 thread1.start(); 
 17 thread2.start(); 
 18 thread3.start(); 
 19 thread4.start(); 
 20 
 21 System.err.println( "Threads started\n" ); 
 22 } 
 23 } 
 24 
 25 class PrintThread extends Thread { 
 26 private int sleepTime; 
 27 
 28 // PrintThread constructor assigns name to thread 
 29 // by calling Thread constructor 
main kết thúc khi thread cuối cùng kết thúc. 
30 public PrintThread( String name ) 
 31 { 
 32 super( name ); 
 33 
 34 // sleep between 0 and 5 seconds 
 35 sleepTime = (int) ( Math.random() * 5000 ); 
 36 
 37 System.err.println( "Name: " + getName() + 
 38 "; sleep: " + sleepTime ); 
 39 } 
 40 
 41 // execute the thread 
 42 public void run() 
 43 { 
 44 // put thread to sleep for a random interval 
 45 try { 
 46 System.err.println( getName() + " going to sleep" ); 
 47 Thread.sleep( sleepTime ); 
 48 } 
 49 catch ( InterruptedException exception ) { 
 50 System.err.println( exception.toString() ); 
 51 } 
 52 
 53 // print thread name 
 54 System.err.println( getName() + " done sleeping" ); 
 55 } 
 56 } 
Gọi constructor lớp 
cha 
Sleep có thể ném ra biệt lệ 
Công việc của thread 
Đồng bộ hóa 
 Nhiều hơn 1 thread cùng truy cập vào một tài nguyên khó có 
thể tránh được đụng độ Cần đến đồng bộ hóa. 
 Dùng phương thức đồng bộ hóa: thêm từ khóa 
synchoronized trước phương thức cần đồng bộ hóa. 
 Dùng câu lệnh đồng bộ hóa 
Đồng bộ hóa 
class Parentheses { 
 void display(String s) { 
 System.out.print("(" + s); 
 try { 
 Thread.sleep(1000); 
 } catch (InterruptedException e) { 
 System.out.println("Interrupted"); 
 } 
 System.out.println(")"); 
 } 
} 
Đồng bộ hóa 
class MyThread implements Runnable { 
 String str; 
 Parentheses parentTheses; 
 Thread t; 
 public MyThread(Parentheses p, String s) { 
 parentTheses = p; 
 str = s; 
 t = new Thread(this); 
 t.start(); 
 } 
 public void run() { 
 parentTheses.display(str); 
 } 
} 
Đồng bộ hóa 
public class MultiThreadDemo { 
 /** 
 * @param args the command line arguments 
 */ 
 public static void main(String[] args) { 
 Parentheses p = new Parentheses(); 
 MyThread name1 = new MyThread(p, "Bob"); 
 MyThread name2 = new MyThread(p, "Mary"); 
 try { 
 name1.t.join(); // tạm dừng cho đến khi thread kết thúc 
 name2.t.join(); 
 } catch (InterruptedException e) { 
 System.out.println("Interrupted"); 
 } 
 } 
} 
Đồng bộ hóa 
 Dùng phương thức đồng bộ 
synchronized void display(String s) { 
} 
 Dùng câu lệnh đồng bộ 
 public void run() { 
 synchronized(parentTheses){ 
 p1.display(str); 
 } 
 } 

File đính kèm:

  • pdfbai_giang_lap_trinh_java_chuong_4_lap_trinh_da_luong_trong_j.pdf