Đa luồng trong java (multithreading in java)
DESCRIPTION
đa luồng trong javaTRANSCRIPT
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
1/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
Dành cho tuyển dụng nhân sự CNTT Liên hệ:
Văn Huy 0977118083 Thành Nhân 0909569156
Đa luô�ng trong java (multithreading in Java)Discussion in 'Bài viết hướng dẫn JSE' started by tranhuyvc, 8/4/10.
Đa luông trong java (multithreading in Java)
Multithread trong java
1.1 Khái niê�m
Thread là một đơn vị (nhóm) chứa các dòng điều khiển trong
một tiến trình hay ứng dụng, chúng được hệ điều hành sử dụng
để thực thi một công việc. Và với cơ chế multithread ứng dụng
của ta có thể thực thi nhiều công việc đồng thời. Mô�i thread se�
có một chỉ số xác định quyền ưu tiên, thread nào có quyền ưu
tiên cao sẽ được thực thi trước, và thấp thì thực thi sau. Việc thực thi và
đánh chỉ số ưu tiên sẽ được thực hiện tự động bởi hệ điều hành
để tránh một thread nào đợi quá lâu mà không được vào xử lý.
Cũng như các ngôn ngữ lập trình khác, java hỗ trợ ngay (trong ba�n
thân ngôn ngữ) khá đây đu� các yêu câu, xử lý của một ứng dụng
multithread.
1.2 Ta�o và qua�n lý thread
Trong chương trình java luôn có một thread chính được thực thi, các
thread khác sẽ được tạo ra như các thread con, việc mở đầu và kết
thúc một ứng dụng được thực hiện bởi thread chính đó.
Hình dưới minh họa vòng đời của một thread:
Đê� ta�o và qua�n lý thread trong java, chúng ta dựa vào lớp Thread và
Runnable interface
Runnable là một interface dùng để các lớp khác implement để sử
du�ng thread. Trong lớp implement đó bắt buộc phải định nghĩa
một phương thức là void run().
Ví du� ta có 2 lớp StringThread implement Runnable, và một lớp
TestClass đê� ta�o ra thread và run nó.
public class StringThread implements Runnable {
private String str;
private int num;
StringThread(String s, int n)
{
str = new String(s);
num = n;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
Vị Trí VIP Dành cho giới thiệu 1 khóa học
Liên hệ: Văn Huy 0977118083 Thành Nhân 0909569156
Dành cho giới thiệu khóa học Liên hệ:
Văn Huy 0977118083 Thành Nhân 0909569156
Dành cho giới thiệu sản phẩm công nghệ Liên hệ:
Văn Huy 0977118083 Thành Nhân 0909569156
Trang chủ Diễn đàn Bài Viết Hướng Dẫn Bài viết hướng dẫn JSE
tranhuyvcAdministrator
Trang chủ Di
Di
ễ
ễ
n đàn
n đàn
Diễn đàn
Tìm trong di
Tìm trong di
ễ
ễ
n đàn
n đàn
Tìm trong diễn đàn Có gì m
Có gì m
ớ
ớ
i?
i?
Có gì mới?
Thành viên Giúp đỡ
Đăng Nhập hoặc Đăng Ký
Tìm kiếm...
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
2/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
*/
@Override
public void run() {
for (int i = 1; i <= num; i++)
System.out.print(str + " ");
}
}
public class TestClass {
/**
* @param args
*/
public static void main(String[] args) {
StringThread t = new StringThread("Thread", 10);
new Thread(t).start();
}
}
Kêt qua� in ra màn hình se� là: Thread Thread Thread Thread Thread
Thread Thread Thread Thread Thread
Thread là một lớp viết sẵn trong java, nó implement Runnable
interface. Nếu chúng ta muốn sử dụng thread chỉ cần viết một
lớp và kế thừa (extends) từ lớp Thread này.
Mô�t sô hàm thông du�ng cu�a Thread
• start bắt đầu thực thi thread
• sleep đưa trạng thái về trạng thái đợi (không thực thi nữa)
• resume thực thi lại thread từ trạng thái đợi hoặc dead-lock
• join đợi để cho đến khi thread này chết
• isAlive kiê�m tra thread còn đang sông hay đã bi� kill
• getName lây tên cu�a thread
• getPriority trả về độ ưu tiên của thread
• setName đă�t tên cho thread
• setPriority đặt độ ưu tiên cho thread
• …
Ví dụ tương tự việc sử dụng thread với Runnable interface, chúng ta
cũng có thể kế thừa tự lớp có sẵn là Thread như sau:
class StringThread extends Thread {
public void run() {
System.out.println("Inherit successfully from Thread class!");
}
}
public class TestClass {
public static void main(String[] args) {
StringThread t = new StringThread();
new Thread(t).start();
}
}
Kêt qua� in ra se� là: Inherit successfully from Thread class!
1.3 Các lớp Timer, TimerTask và SchedulingTask
Timer là một lớp tiện ích giúp cho việc lập lịch và kiểm soát
việc thực thi một task vụ nào đó. Ví du� ba�n muôn dùng viê�c
câ�p nhâ�t thông trong 5 phút tới, hay thông tin chỉ được tồn tại
10h sau đó sẽ tự động bị xóa đi,… Mô�t sô hàm thông du�ng
trong Timer như:
• schedule lên lịch để thực thi task khi nào bắt đầu, kêt thúc hay
lă�p la�i, …
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
3/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
• cancel dừng timer và hủy tất cả các task đã lên lịch trong timer
• purge xóa tất cả các task đã dùng trong hàng đợi timer
TimerTask là một lớp trừu tượng implement Runnable interface, nó giúp
cho việc lập lịch thực thi các thread
Ví dụ ta có một lớp MyTimerTask kế thừa từ TimerTask như bên dưới
class MyTimerTask extends TimerTask {
public void run() {
System.out.println("Running the scheduled task by Timer");
System.gc();
}
}
public class TestClass {
public static void main(String[] args) {
Timer timer = new Timer();
MyTimerTask task = new MyTimerTask();
timer.schedule(task, 3000, 2000);//Execute task after 3 senconds and then
repeat in 2 seconds period
}
}
Kêt qua� in ra màn hình sau 5 giây se� là: Running the scheduled task
by Timer
Running the scheduled task by Timer
1.4 Xử lý các vấn đề chúng trong multithread như synchronized, lock,
dead lock, wait, notify …
Đông bô� (Synchronization) là cơ chế giúp cho đồng bộ việc truy
câ�p cùng tài nguyên cu�a nhiêu thread khác nhau. Như chúng ta
biết vì cơ chế thread là cơ chế làm việc đồng thời do đó có khả
năng một tài nguyên sẽ bị truy cập bởi nhiều thread khác nhau.
Ví dụ ta xây dựng 3 lớp Socola, Producer, Consumer. Lớp Socola chứa
thông tin, lớp Producer tạo thông tin và gán vào cho Socola, Lớp
Consumer se� ăn (tiêu thu�) thông tin đó.
public class TestClass {
public class Socola {
private int contents = 0;
public boolean isRemainingContents;
public synchronized int get() {
//print onto screen
System.out.println("\tConsumer get " + this.contents);
return contents;
}
public synchronized void set(int piContents) {
this.contents = piContents;
//print onto screen
System.out.println("Producer set " + this.contents);
}
}
public class Producer extends Thread {
private Socola socola;
Producer(Socola pSocola) {
socola = pSocola;
}
public void run() {
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
4/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
for(int i = 0; i < 10; i++) {
socola.set(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public class Consumer extends Thread {
private Socola socola;
Consumer(Socola pSocola) {
socola = pSocola;
}
public void run() {
for(int i = 0; i < 10; i++) {
socola.get();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public static void main(String[] args) {
TestClass t = new TestClass();
Socola s = t.new Socola();
Producer p = t.new Producer(s);
Consumer c = t.new Consumer(s);
p.start();
c.start();
}
}
Kêt qua� in ra màn hinh se� không giông nhau ta�i các lân cha�y,
ví du� 1 lân cha�y:
Producer set 0
Consumer get 0
Producer set 1
Consumer get 1
Producer set 2
Consumer get 2
Producer set 3
Consumer get 3
Producer set 4
Consumer get 4
Consumer get 4
Producer set 5
Producer set 6
Consumer get 6
Producer set 7
Consumer get 7
Consumer get 7
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
5/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
Producer set 8
Consumer get 8
Producer set 9
Từ ví dụ trên ta thấy có chung một tài nguyên là Socola mà có 2 đôi
tượng cùng truy cập � có thê� sinh ra mâu thuâ�n khi truy câ�p
đồng thời. Bây giờ ta muốn là chỉ khi Producer tạo ra thông tin thì
Consumer mới ăn thông tin đó, không muôn Consumer ăn nhiêu lân
cùng mô�t thông tin, khi Producer đang ta�o ra thông tin thì Consumer
đứng chờ, khi nào Producer tạo ra thông tin xong thì Consumer mới vào
ăn thông tin. vậy thì ta phải dùng cơ chế đồng bộ trong java với
các từ khóa synchronized, wait(), notify(), notifyAll() và chi�nh la�i 2
hàm get và set trong lớp Socola như sau:
public synchronized int get() {
while(isRemainingContents == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
isRemainingContents = false;
//print onto screen
System.out.println("\tConsumer get " + this.contents);
//Notify Producer to produce new contents
notifyAll();
return contents;
}
public synchronized void set(int piContents) {
while(isRemainingContents == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
this.contents = piContents;
isRemainingContents = true;
//print onto screen
System.out.println("Producer set " + this.contents);
//Notify Consumer to eat this contents
notifyAll();
}
}
Kết quả in ra luôn luôn như sau:
Producer set 0
Consumer get 0
Producer set 1
Consumer get 1
Producer set 2
Consumer get 2
Producer set 3
Consumer get 3
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
6/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
Producer set 4
Consumer get 4
Producer set 5
Consumer get 5
Producer set 6
Consumer get 6
Producer set 7
Consumer get 7
Producer set 8
Consumer get 8
Producer set 9
Consumer get 9
Có 3 hàm cân đê� ý:
• wait() đưa thread vào trạng thái chờ khi nào được notify() hoă�c
notifyAll() thì sẽ thực hiện tiếp
• notify() đánh thức thread đang đợi, nếu có nhiều thread đang đợi, thì
một trong những thread đó được đánh thức thôi.
• notifyAll() đánh thức tất cả các thread đang đợi
Note: Nhiêu khi chúng ta không cân hoă�c không thê� đông bô�
nguyên hàm (dùng synchronized) mà chi� cân đông bô� mô�t vài
dòng code truy câ�p tài nguyên, ta có thể dùng khối đồng bộ như
sau:
synchronized(object) {
// Các câu lê�nh cân đông bô�
}
Ví du�: Khi bạn sử dụng lớp Socola là của khách hàng bạn đưa
cho, bạn không thể chỉnh sửa định nghĩa hàm get và set trong
Socola được vậy thì bạn có thể dùng khối đồng bộ bên trên
cũng sẽ cho kết quả tương tự.
Deadlock (khóa chêt) trong xử lý đa luồng xảy là khi mà một thread
được đưa vào trạng thái chờ tài nguyên và không bao giờ được đánh thức
lại vì tại nguyên đó không bao giờ được giải phóng. Để rõ hơn ta ví
du� A, B, C là thread trong trạng thái chờ; rA, rB, rC là tài nguyên dùng
chung và chỉ duy nhất một thread sử dụng trong một thời
điê�m, tài nguyên chỉ được giải phóng khi thread làm xong và không
sử dụng nữa.
• A giữ rA, chờ rB
• B giữ rB, chờ rC
• C giữ rC, chờ rA
Từ ví dụ trên ta thấy A, B, C là những thread đang ở trong trạng thái
chờ tài nguyên, tuy nhiên tài nguyên của chúng không bao giờ được
gia�i phóng, và mãi mãi chúng cứ chờ thôi. Đê� ha�n chê deadlock thì
chúng ta phải đưa ra, ca�i tiên viê�c câp phát, thu hôi tài nguyên
cho các thread và hiê�n này có khá nhiêu thuâ�t toán ca�i tiên
viê�c này, tuy nhiên không có cái nào giúp tránh hoàn toàn deadlock.
1.5 Những lớp tiện ích trong lập trình đa luồng (multithread)
Trong java đã xây dựng một vài lớp giúp hỗ trợ lập trình đa luồng,
chúng được đặt trong gói Concurent như: Semaphore, Lock, Condition,
ConcurrentMap, ConcurrentLinkedQueue, …
Semaphore là một lớp tiện ích đã xây dựng trong java (java 5) dùng
để giới hạn số lượng thread truy cập đến tài nguyên. Đâu tiên
thread cần yêu cầu sự chấp nhận truy cập tài nguyên từ
semaphore băng hàm acquire, và thread sẽ về trạng thái đợi (block)
cho đến khi được chấp nhận, khi thread được chấp nhận nó thực
hiê�n công viê�c cu�a nó xong se� go�i hàm release đê� tra� vê
cho semaphore một sự chấp nhận còn trống để semaphore cấp
cho thread khác.
Lock là một interface được xây dựng nhằm mở rộng hơn việc
quản lý truy cập tài nguyên trong nhiều thread hơn so với cách dùng
synchronized chẳng hạn như có thể hỗ trợ nhiều điều kiện
(condition object) trong lock, hoặc hỗ trợ nhiều thuật toán cho
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
7/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
chain-lock để tránh deadlock tốt hơn, … Khi dùng Lock chúng ta nên
theo một template chuẩn như sau:
Lock l = ...;
l.lock();
try {
// Các task truy cập tài nguyên bảo vệ bởi lock đặt ở đây
} finally {
l.unlock();
}
Condition là một interface dùng để nhóm cách xử lý trong các phương
thức (wait, notify, notifyAll) của lớp Object vào thành một đối tượng
nhằm đưa ra nhiều chọn lựa hơn trong việc đồng bộ, ví du�
chúng ta có thê� dùng nhiêu condition và khi nào chúng ta muôn đánh
thức chính xác điều kiện nào được sử dụng tài nguyên.
Ví du� ta dùng la�i ví du� Consumer-Producer ở trên, thêm vào 2 biên
lock, condition và chỉnh sửa hai làm get và put thế là ta cũng được kết
quả như dùng với từ khóa synchronized:
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
public int get() {
int result;
lock.lock();
try {
while(isRemainingContents == false) {
try {
condition.await();
} catch (InterruptedException e) {
}
}
isRemainingContents = false;
//print onto screen
System.out.println("\tConsumer get " + this.contents);
//get value
result = contents;
//Notify Producer to produce new contents
condition.signalAll();
} finally {
lock.unlock();
}
return result;
}
public void set(int piContents) {
lock.lock();
try {
while(isRemainingContents == true) {
try {
condition.await();
} catch (InterruptedException e) {
}
}
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
8/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
tranhuyvc, 8/4/10 #1
giant26, 1/1/12 #2
this.contents = piContents;
isRemainingContents = true;
//print onto screen
System.out.println("Producer set " + this.contents);
//Notify Consumer to eat this contents
condition.signalAll();
} finally {
lock.unlock();
}
}
Kêt qua� luôn luôn là thê này:
Producer set 0
Consumer get 0
Producer set 1
Consumer get 1
Producer set 2
Consumer get 2
Producer set 3
Consumer get 3
Producer set 4
Consumer get 4
Producer set 5
Consumer get 5
Producer set 6
Consumer get 6
Producer set 7
Consumer get 7
Producer set 8
Consumer get 8
Producer set 9
Consumer get 9
ConcurrentMap là một interface kế thừa từ Map dùng để cải tiến,
tối ưu hơn khi chạy Map trong ứng dụng đa luồng (multithread)
Ví dụ cách dùng ConcurrentHashMap tương tự dùng Map, tuy nhiên
người ta đã thống kê là nếu chương trình có càng nhiều thread truy
câ�p vào cMap này thì dùng ConcurrentMap se� cho performance tôt
hơn rất nhiều so với dùng Map với đồng bộ kiểu synchronized
public static ConcurrentMap<String,String> cMap =
new ConcurrentHashMap<String, String>(1000);
public static void main(String[] args) {
cMap.putIfAbsent("id", "1");
cMap.putIfAbsent("name", "kien");
cMap.putIfAbsent("email", "[email protected]");
System.out.println(cMap); //Print to screen
}
Kêt qua�: {name=kien, [email protected], id=1}
Ðề: Đa luông trong java (multithreading in Java)
Cho em hỏi sự khác biệt giữa Thread và Runable, khi nào thì sử dụng cái
nào vậy anh?
giant26
19/07/2012 Đa luông trong java (multithreading in Java) | Cộng đồng Java Việt Nam | Java Việt Nam | Java SE, Java…
9/9congdongjava.com/forum/threads/Đa-luông-trong-java-multithreading-in-java.802/
Vietnamese (VI) Liên hệ với Chúng tôiTrang chủ Top
Forum software by XenForo™ ©2011 XenForo Ltd. Điều khoản & Quy định Global Feed
(Bạn phải đăng ký thành viên hoặc đăng nhập vào diễn đàn nếu muốn trả lời bài viết này.)
TweetTweet 0
Chia sẻ trang này
Member
Recommend One person recommends this. Be the first of your friends.
Trang chủ Diễn đàn Bài Viết Hướng Dẫn Bài viết hướng dẫn JSE