41
A TUYN
Mc tiêu:
Sau khi kt thúc ching này, bn có th:
nh ngha mt lung
Mô t đa tuyn
To và qun lý lung
Hiu đc vòng đi ca lung
Mô t mt lung him
Gii thích tp hp các lung u tiên nh th nào
Gii thích đc s cn thit ca s đng b
Hiu đc cách thêm vào các t khoá synchronized (đng b) nh th
nào
Lit kê nhng điu không thun li ca s đng b
Gii thích vai trò ca các phng thc wait() (đi), notify() (thông
báo) và notifyAll().
Mô t mt điu kin b tc (deadlock).
1. Gii thiu
Mt lung là mt thuc tính duy nht ca Java. Nó là đn v nh nht ca đon
mã có th thi hành đc mà thc hin mt công vic riêng bit. Ngôn ng Java và máy o
Java c hai là các h thng đc phân lung
2. a tuyn
Java h tr đa tuyn, mà có kh nng làm vic vi nhiu lung. Mt ng dng có
th bao hàm nhiu lung. Mi lung đc đng ký mt công vic riêng bit, mà chúng
đc thc thi đng thi vi các lung khác.
a tuyn gi thi gian nhàn ri ca h thng thành nh nht. iu này cho phép
bn vit các chng trình có hiu qu cao vi s tn dng CPU là ti đa. Mi phn ca
chng trình đc gi mt lung, mi lung đnh ngha mt đng dn khác nhau ca s
thc hin. ây là mt thit k chuyên dùng ca s đa nhim.
Trong s đa nhim, nhiu chng chng trình chy đng thi, mi chng trình
có ít nht mt lung trong nó. Mt vi x lý thc thi tt c các chng trình. Cho dù nó có
th xut hin mà các chng trình đã đc thc thi đng thi, trên thc t b vi x lý
nhy qua li gia các tin trình.
3. To và qun lý lung
Khi các chng trình Java đc thc thi, lung chính luôn luôn đang đc thc
hin. ây là 2 nguyên nhân quan trng đi vi lung chính:
Các lung con s đc to ra t nó.
Nó là lung cui cùng kt thúc vic thc hin. Trong chc lát lung
chính ngng thc thi, chng trình b chm dt.
Cho dù lung chính đc to ra mt cách t đng vi chng trình thc thi, nó có
th đc điu khin thông qua mt lung đi tng.
Các lung có th đc to ra t hai con đng:
Trình bày lp nh là mt lp con ca lp lung, ni mà phng thc run() ca
lp lung cn đc ghi đè. Ly ví d:
42
Class Mydemo extends Thread
{
//Class definition
public void run()
{
//thc thi
}
}
Trình bày mt lp mà lp này thc hin lp Runnable. Ri thì đnh ngha
phng thc run().
Class Mydemo implements Runnable
{
//Class definition
public void run()
{
//thc thi
}
}
Chng trình 8.1 s ch ra s điu khin lung chính nh th nào
Chng trình 8.1
import java.io.*;
public class Mythread extends Thread{
/**
* Mythread constructor comment.
*/
public static void main(String args[]){
Thread t = Thread.currentThread();
System.out.println("The current Thread is :" + t);
t.setName("MyJavaThread");
System.out.println("The thread is now named: " + t);
try{
for(int i = 0; i <3;i++){
System.out.println(i);
Thread.sleep(1500);
}
}catch(InterruptedException e){
System.out.println("Main thread interupted");
}
}
}
Hình sau đây s ch ra kt qu xut ra màn hình ca chng trình trên
43
Hình 8.1 Lung
Trong kt qu xut ra trên
Mi lung trong chng trình Java đc đng ký cho mt quyn u tiên. Máy o
Java không bao gi thay đi quyn u tiên ca lung. Quyn u tiên vn còn là hng s
cho đn khi lung b ngt.
Mi lung có mt giá tr u tiên nm trong khong ca mt
Thread.MIN_PRIORITY ca 1, và mt Thread.MAX_PRIORITY ca 10. Mi lung ph
thuc vào mt nhóm lung, và mi nhóm lung có quyn u tiên ca chính nó. Mi
lung đc nhn mt hng s u tiên ca phng thc Thread.PRIORITY là 5. Mi
lung mi tha k quyn u tiên ca lung mà to ra nó.
Lp lung có vài phng thc khi dng, hai trong s các phng thc khi
dng đc đ cp đn di đây:
public Thread(String threadname)
Cu trúc mt lung vi tên là “threadname”
public Thread()
Cu trúc mt lung vi tên “Thread, đc ràng buc vi mt s; ly ví d,
Thread-1, Thread-2, v.v…
Chng trình bt đu thc thi lung vi vic gi phng thc start(), mà phng
thc này ph thuc vào lp lung. Phng thc này, ln lt, vin dn phng thc
run(), ni mà phng thc đnh ngha tác v đc thc thi. Phng thc này có th vit
đè lên lp con ca lp lung, hoc vi mt đi tng Runnable.
4. Vòng đi ca Lung
[main, 5 , main]
N
hóm lung mà nó ph thuc vào
Quyn u tiên đc đt bi JVM
Tên ca lung
44
Hình 8.3 Vòng đi ca lung
5. Phm vi ca lung và các phng thc ca lp lung
Mt lung đã đc to mi gn đây là trong phm vi “sinh”. Lung không bt
đu chy ngay lp tc sau khi nó đc to ra. Nó đi phng thc start() ca chính nó
đc gi. Cho đn khi, nó là trong phm vi “sn sàng đ chy”. Lung đi vào phm vi
“đang chay” khi h thng đnh rõ v trí lung trong b vi x lý.
Bn có th s dng phng thc sleep() đ tm thi treo s thc thi ca lung.
Lung tr thành sn sàng sau khi phng thc sleep kt thúc thi gian. Lung Sleeping
không s dng b vi x lý. lung đi vào phm vi “waiting” (đi) khi mt lung đang
chy gi phng thc wait() (đi).
Khi các lung khác liên kt vi các đi tng, gi phng thc notify(), lung đi
vào tr li phm vi “ready” (sn sàng) Lung đi vào phm vi “blocked” (khi) khi nó
đang thc thi các phép toán vào/ra (Input/output). Nó đi vào phm vi “ready” (sn sàng)
khi các phng thc vào/ra nó đang đi cho đn khi đc hoàn thành. Lung đi vào
phm vi “dead” (cht) sau khi phng thc run() đã đc thc thi hoàn toàn, hoc khi
phng thc stop() (dng) ca nó đc gi.
Thêm vào các phng thc đã đc đ cp trên, Lp lung cng có các phng
thc sau:
Phng thc Mc đích
Enumerate(Thread t) Sao chép tt c các lung hin hành vào mng đc ch
đnh t nhóm ca các lung, và các nhóm con ca nó.
getName() Tr v tên ca lung
isAlive() Tr v úng, nu lung là vn còn tn ti (sng)
getPriority() Tr v quyn u tiên ca lung
setName(String name) t tên ca lung là tên mà lung đc truyn nh là
mt tham s.
join() i cho đn khi lung cht.
isDaemon(Boolean on) Kim tra nu lung là lung mt lung him.
resume() ánh du lung nh là lung him hoc lung ngi s
dng ph thuc vào giá tr đc truyn vào.
sleep() Hoãn lung mt khoáng thi gian chính xác.
start() Gi phng thc run() đ bt đu mt lung.
45
Bng 8.1 Các phng thc ca mt lp lung
Bng k hoch Round-robin (bng kin ngh ký tên vòng tròn) liên quan đn các
lung vi cùng quyn u tiên đc chim hu quyn u tiên ca mi lung khác. Chúng
chia nh thi gian mt cách t đng trong theo kiu k hoch xoay vòng này.
Phiên bn mi nht ca Java không h tr các phng thc Thread.suspend() (trì
hoãn), Thread.resume() (phc hi) và Thread.stop() (dng), nh là các phng thc
resume() (phc hi) và suspend() (trì hoãn) đc thiên v s đình tr (deadlock), trong
khi phng thc stop() không an toàn.
6. Thi gian biu lung
Hu ht các chng trình Java làm vic vi nhiu lung. CPU cha đng cho vic
chy chng trình ch mt lung ti mt khong thi gian. Hai lung có cùng quyn u
tiên trong mt chng trình hoàn thành trong mt thi gian CPU. Lp trình viên, hoc
máy o Java, hoc h điu hành chc chn rng CPU đc chia s gia các lung. iu
này đc bit nh là bng thi gian biu lung.
Không có máy o Java nào thc thi rành mch cho bng thi gian biu lung. Mt
s nn Java h tr vic chia nh thi gian. đây, mi lung nhn mt phn nh ca thi
gian b vi x lý, đc gi là đnh lng. Lung có th thc thi tác v ca chính nó trong
sut khong thi gian đnh lng đy. Sau khong thi gian này đc vt qua, lung
không đc nhn nhiu thi gian đ tip tc thc hin, ngay c nu nó không đc hoàn
thành vic thc hin ca nó. Lung k tip ca lung có quyn u tiên bng nhau này s
ly khong thi gian thay đi ca b vi x lý. Java là ngi lp thi gian biu chia nh tt
c các lung có cùng quyn u tiên cao.
Phng thc setPriority() ly mt s nguyên (integer) nh là mt tham s có th
hiu chnh quyn u tiên ca mt lung. ây là giá tr có phm vi thay đi t 1 đn 10,
mc khác, phng thc đa ra mt ngoi l (by li) đc gi là
IllegalArgumentException (Chp nhn tham s trái lut)
Phng thc yield() (li nhun) đa ra các lung khác mt kh nng đ thc thi.
Phng thc này đc thích hp cho các h thng không chia nh thi gian (non-time-
sliced), ni mà các lung hin thi hoàn thành vic thc hin trc khi các lung có
quyn u tiên ngang nhau k tip tip qun. đây, bn s gi phng thc yield() ti
nhng khon thi gian riêng bit đ có th tt c các lung có quyn u tiên ngang nhau
chia s thi gian thc thi CPU.
Chng trình 8.2 chng minh quyn u tiên ca lung:
Chng trình 8.2
class PriorityDemo {
Priority t1,t2,t3;
public PriorityDemo(){
t1 = new Priority();
t1.start();
t2 = new Priority();
t2.start();
t3 = new Priority();
t3.start();
}
public static void main(String args[]){
46
new PriorityDemo();
}
class Priority extends Thread implements Runnable{
int sleep;
int prio = 3;
public Priority(){
sleep += 100;
prio++;
setPriority(prio);
}
public void run(){
try{
Thread.sleep(sleep);
System.out.println("Name "+ getName()+" Priority
= "+ getPriority());
}catch(InterruptedException e){
System.out.println(e.getMessage());
}
}
}
}
Kt qu hin th nh hình 8.4
Hình 8.4 Quyn u tiên lung
7. Lung him
Mt chng trình Java b ngt ch sau khi tt c các lung b cht. Có hai kiu
lung trong mt chng trình Java:
Các lung ngi s dng
Lung him
Ngi s dng to ra các lung ngi s dng, trong khi các lung đc ch đnh
nh là lung “background” (nn). Lung him cung cp các dch v cho các lung khác.
Máy o Java thc hin tin trình thoát, khi và ch khi lung him vn còn sng. Máy o
47
Java có ít nht mt lung him đc bit đn nh là lung “garbage collection” (thu
lm nhng d liu vô ngha - dn rác). Lung dn rác thc thi ch khi h thng không
có tác v nào. Nó là mt lung có quyn u tiên thp. Lp lung có hai phng thc đ
tha thun vi các lung him:
public void setDaemon(boolean on)
public boolean isDaemon()
8. a tuyn vi Applets
Trong khi đa tuyn là rt hu dng trong các chng trình ng dng đc lp, nó
cng đáng đc quan tâm vi các ng dng trên Web. a tuyn đc s dng trên web,
cho ví d, trong các trò chi đa phng tin, các bc nh đy sinh khí, hin th các dòng
ch chy qua li trên biu ng, hin th đng h thi gian nh là mt phn ca trang Web
v.vv… Các chc nng này cu thành các trang web làm quyn r và bt mt.
Chng trình Java da trên Applet thng s dng nhiu hn mt lung. Trong
đa tuyn vi Applet, lp java.applet.Applet là lp con đc to ra bi ngi s dng đnh
ngha applet. T đó, Java không h tr nhiu k tha vi các lp, nó không th thc hin
đc trc tip lp con ca lp lung trong các applet. Tuy nhiên, chúng ta s dng mt
đi tng ca lung ngi s dng đã đnh ngha, mà các lung này, ln lt, dn xut t
lp lung. Mt lung đn gin xut hin s đc thc thi ti giao din (Interface)
Runnable
Chng trình 8.3 ch ra điu này thc thi nh th nào:
Chng trình 8.3
import java.awt.*;
import java.applet.*;
public class Myapplet extends Applet implements Runnable {
int i;
Thread t;
/**
* Myapplet constructor comment.
*/
public void init(){
t = new Thread(this);
t.start();
}
public void paint(Graphics g){
g.drawString(" i = "+i,30,30);
}
public void run(){
for(i = 1;i<=20;i++){
try{
repaint();
Thread.sleep(500);
}catch(InterruptedException e){
System.out.println(e.getMessage());
}
48
}
}
}
Trong chng trình này, chúng ta to ra mt Applet đc gi là Myapplet, và
thc thi giao din Runnable đ cung cp kh nng đa tuyn cho applet. Sau đó, chúng ta
to ra mt th nghim (instance) cho lp lung, vi th nghim applet hin thi nh là
mt tham s đ thit lp (khi dng). Ri thì chúng ta vin dn phng thc start() ca
lung th nghim này. Ln lt, ri s vin dn phng thc run(), mà phng thc này
thc s là đim bt đu cho phng thc này. Chúng ta in s t 1 đn 20 vi thi gian
kéo tr là 500 miligiây gia mi s. Phng thc sleep() đc gi đ hoàn thành thi
gian kéo tr này. ây là mt phng thc tnh đc đnh ngha trong lp lung. Nó cho
phép lung nm yên (ng) trong khon thi gian hn ch.
Xut ra ngoài có dng nh sau:
Hình 8.5 a tuyn vi Applet
9. Nhóm lung
Mt lp nhóm lung (ThreadGroup) nm bt mt nhóm ca các lung. Ly ví d,
mt nhóm lung trong mt trình duyt có th qun lý tt c các lung ph thuc vào mt
đn th applet. Tt c các lung trong máy o Java ph thuc vào các nhóm lung mc
đnh. Mi nhóm lung có mt nhóm ngun cha. Vì th, các nhóm t mt cu trúc dng
cây. Nhóm lung “h thng” là gc ca tt c các nhóm lung. Mt nhóm lung có th là
thành phn ca c các lung, và các nhóm lung.
Hai kiu nhóm lung thit lp (khi dng) là:
public ThreadGroup(String str)
đây, “str” là tên ca nhóm lung mi nht đc to ra.
public ThreadGroup(ThreadGroup tgroup, String str)
đây, “tgroup” ch ra lung đang chy hin thi nh là lung cha, “str” là tên ca
nhóm lung đang đc to ra.
Mt s các phng thc trong nhóm lung (ThreadGroup) đc cho nh sau:
public synchronized int activeCount()
49
Tr v s lng các lung kích hot hin hành trong nhóm lung
public sunchronized int activeGroupCount()
Tr v s lng các nhóm hot đng trong nhóm lung
public final String getName()
Tr v tên ca nhóm lung
public final ThreadGroup getParent()
Tr v cha ca nhóm lung
10. S đng b lung
Trong khi đang làm vic vi nhiu lung, nhiu hn mt lung có th mun thâm
nhp cùng bin ti cùng thi đim. Ly ví d, mt lung có th c gng đc d liu, trong
khi lung khác c gng thay đi d liu. Trong trng hp này, d liu có th b sai lc.
Trong nhng trng hp này, bn cn cho phép mt lung hoàn thành trn vn
tác v ca nó (thay đi giá tr), và ri thì cho phép các lung k tip thc thi. Khi hai
hoc nhiu hn các lung cn thâm nhp đn mt tài nguyên đc chia s, bn cn chc
chn rng tài nguyên đó s đc s dng ch bi mt lung ti mt thi đim. Tin trình
này đc gi là “s đng b” (synchronization) đc s dng đ lu tr cho vn đ này,
Java cung cp duy nht, ngôn ng cp cao h tr cho s đng b này. Phng thc “đng
b” (synchronized) báo cho h thng đt mt khóa vòng mt tài nguyên riêng bit.
Mu cht ca s đng b hóa là khái nim “monitor” (s quan sát, giám sát),
cng đc bit nh là mt bng mã “semaphore” (bng mã). Mt “monitor” là mt đi
tng mà đc s dng nh là mt khóa qua li duy nht, hoc “mutex”. Ch mt lung
có th có riêng nó mt s quan sát (monitor) ti mi thi đim đc đa ra. Tt c các
lung khác c gng thâm nhp vào monitor b khóa s b trì hoãn, cho đn khi lung đu
tiên thoát khi monitor. Các lung khác đc báo ch đi monitor. Mt lung mà
monitor ca riêng nó có th thâm nhp tr li cùng monitor.
1. Mã đng b
Tt c các đi tng trong Java đc liên kt vi các monitor (s giám sát) ca
riêng nó. đng nhp vào monitor ca mt đi tng, lp trình viên s dng t khóa
synchronized (đng b) đ gi mt phng thc hiu chnh (modified). Khi mt lung
đang đc thc thi trong phm vi mt phng thc đng b (synchronized), bt k lung
khác hoc phng thc đng b khác mà c gng gi nó trong cùng th nghim s phi
đi.
Chng trình 8.4 chng minh s làm vic ca t khóa synchronized (s đng b).
đây, lp “Target” (mc tiêu) có mt phng thc “display()” (hin th) mà phng
thc này ly mt tham s kiu s nguyên (int). S này đc hin th trong phm vi các
cp ký t “< > # s # <>”. Phng thc “Thread.sleep(1000) tm dng lung hin ti sau
khi phng thc “display()” đc gi.
Thit lp (khi dng) ca lip “Source” ly mt tham chiu đn mt đi tng “t”
ca lp “Target”, và mt bin s nguyên (integer). đây, mt lung mi cng đc to
ra. Lung này gi phng thc run() ca đi tng “t”. Lp chính “Synch” th nghim
lp “Target” nh là “target (mc tiêu), và to ra 3 đi tng ca lp “Source” (ngun).
Cùng đi tng “target” đc truyn cho mi đi tng “Source”. Phng thc “join()”
(gia nhp) làm lung đc gi đi cho đn khi vic gi lung b ngt.
50
Chng trình 8.4
class Target {
/**
* Target constructor comment.
*/
synchronized void display(int num) {
System.out.print("<> "+num);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
System.out.println("Interrupted");
}
System.out.println(" <>");
}
}
class Source implements Runnable{
int number;
Target target;
Thread t;
/**
* Source constructor comment.
*/
public Source(Target targ,int n){
target = targ;
number = n;
t = new Thread(this);
t.start();
}
public void run(){
synchronized(target) {
target.display(number);
}
}
}
class Sync {
/**
* Sync constructor comment.
*/
public static void main(String args[]){
Target target = new Target();
int digit = 10;
Source s1 = new Source(target,digit++);
51
Source s2 = new Source(target,digit++);
Source s3 = new Source(target,digit++);
try{
s1.t.join();
s2.t.join();
s3.t.join();
}catch(InterruptedException e){
System.out.println("Interrupted");
}
}
}
Kt qu hin th nh hình cho di đây:
Hình 8.6 Kt qu hin th ca chng trình 8.4
Trong chng trình trên, có mt “dãy s” đng nhp đc hin th “display()”.
iu này có ngha là vic thâm nhp b hn ch mt lung ti mi thi đim. Nu t khóa
synchronized đt trc b b quên trong phng thc “display()” ca lp “Target”, tt c
lung trên có th cùng lúc gi cùng phng thc, trên cùng đi tng. iu kin này
đc bit đn nh là “loi điu kin” (race condition). Trong trng hp này, vic xut ra
ngoài s đc ch ra nh hình 8.7
52
Hình 8.7 Kt qu hin th ca chng trình 8.7 không có s đng b
2. S dng khi đng b (Synchronized Block)
To ra các phng thc synchronzed (đng b) trong phm vi các lp là mt con
đng d dàng và có hiu qu ca vic thc hin s đng b. Tuy nhiên, điu này không
làm vic trong tt c các trng hp.
Hãy xem mt trng hp ni mà lp trình viên mun s đng b đc xâm nhp
vào các đi tng ca lp mà không đc thit k cho thâm nhp đa tuyn. Tc là, lp
không s dng các phng thc đng b. Hn na, mã ngun là không có giá tr. Vì th
t khoá synchronized không th đc thêm vào các phng thc thích hp trong phm vi
lp.
đng b thâm nhp mt đi tng ca lp này, tt c chúng gi các phng
thc mà lp này đnh ngha, đc đt bên trong mt khi đng b. Tt c chúng s dng
chung mt câu lnh đng b đc cho nh sau:
synchronized(object)
{
// các câu lnh đng b
}
đây, “object” (đi tng) là mt tham chiu đn đi tng đc đng b. Du
ngoc móc không cn thit khi ch mt câu lnh đc đng b. Mt khi đng b bo
đm rng nó gi đn mt phng thc (mà là thành phn ca đi tng) xut hin ch sau
khi lung hin hành đã đc tham nhp thành công vào monitor (s quan sát) ca đi
tng.
Chng trình 8.5 ch ra câu lnh đng b s dng nh th nào:
Chng trình 8.5
class Target {
/**
* Target constructor comment.
*/
synchronized void display(int num) {
System.out.print("<> "+num);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
System.out.println("Interrupted");
}
53
System.out.println(" <>");
}
}
class Source implements Runnable{
int number;
Target target;
Thread t;
/**
* Source constructor comment.
*/
public Source(Target targ,int n){
target = targ;
number = n;
t = new Thread(this);
t.start();
}
// đng b gi phng thc display()
public void run(){
synchronized(target) {
target.display(number);
}
}
}
class Synchblock {
/**
* Synchblock constructor comment.
*/
public static void main(String args[]){
Target target = new Target();
int digit = 10;
Source s1 = new Source(target,digit++);
Source s2 = new Source(target,digit++);
Source s3 = new Source(target,digit++);
try{
s1.t.join();
s2.t.join();
s3.t.join();
}catch(InterruptedException e){
System.out.println("Interrupted");
}
}
}
54
đây, t khóa synchronized không hiu chnh phng thc “display()”. T khóa
này đc s dng trong phng thc run() ca lp “Target” (mc tiêu). Kt qu xut ra
màn hình tng t vi kt qu ch ra hình s 8.6
3. S không thun li ca các phng thc đng b
Ngi lp trình thng vit các chng trình trên các đn th lung. Tt nhiên
các trng thái này chc chn không li ích cho đa tuyn. Ly ví d, lng không tn dng
vic thc thi ca trình biên dch. Trình biên dch Java t Sun không cha nhiu phng
thc đng b.
Các phng thc đng b không thc thi tt nh là các phng thc không đng
b. Các phng thc này chm hn t ba đn bn ln so vi các phng thc tng ng
không đng b. Trong trng thái ni mà vic thc thi là có gii hn, các phng thc
đng b b ngn nga.
11. K thut “wait-notify” (đi – thông báo)
Lung chia các tác v thành các đn v riêng bit và logic (hp lý). iu này thay
th các trng hp (s kin) chng trình lp. Các lung loi tr “polling” (kim soát
vòng).
Mt vòng lp mà lp li vic mt s điu kin thng thc thi “polling” (kim
soát vòng). Khi điu kin nhn giá tr là True (đúng), các câu lnh phúc đáp đc thc
hin. ây là tin trình thng b phí thi gian ca CPU. Ly ví d, khi mt lung sinh ra
mt s d liu, và các lung khác đang chi phi nó, lung sinh ra phi đi cho đn khi
các lung s dng nó hoàn thành, trc khi phát sinh ra d liu.
tránh trng hp kim soát vòng, Java bao gm mt thit k tt trong tin
trình k thut truyn thông s dng các phng thc “wait()” (đi), “notify()” (thông
báo) và “notifyAll()” (thông báo ht). Các phng thc này đc thc hin nh là các
các phng thc cui cùng trong lp đi tng (Object), đ mà tt c các lp có th thâm
nhp chúng. Tt c 3 phng thc này có th đc gi ch t trong phm vi mt phng
thc đng b (synchronized).
Các chc nng ca các phng thc “wait()”, “notify()”, và “notifyAll()” là:
Phng thc wait() nói cho vic gi lung trao cho monitor (s giám sát), và
nhp trng thái “sleep” (ch) cho đn khi mt s lung khác thâm nhp cùng
monitor, và gi phng thc “notify()”.
Phng thc notify() đánh thc, hoc thông báo cho lung đu tiên mà đã gi
phng thc wait() trên cùng đi tng.
Phng thc notifyAll() đánh thc, hoc thông báo tt c các lung mà đã
gi phng thc wait() trên cùng đi tng.
Quyn u tiên cao nht lung chy đu tiên.
Cú pháp ca 3 phng thc này nh sau:
final void wait() throws IOException
final void notify()
final void notifyAll()
55
Các phng thc wait() và notify() cho phép mt đi tng đc chia s đ tm
ngng mt lung, khi đi tng tr thành không còn giá tr cho lung. Chúng cng cho
phép lung tip tc khi thích hp.
Các lung bn thân nó không bao gi kim tra trng thái ca đi tng đã chia s.
Mt đi tng mà điu khin các lung khách (client) ca chính nó theo kiu này
đc bit nh là mt monitor (s giám sát). Trong các thut ng cht ch ca Java, mt
monitor là bt k đi tng nào mà có mt s mã đng b. Các monitor đc s dng
cho các phng thc wait() và notify(). C hai phng thc này phi đc gi trong mã
đng b.
Mt s đim cn nh trong khi s dng phng thc wait():
Lung đang gi đa vào CPU
Lung đang gi đa vào khóa
Lung đang gi đi vào vùng đi ca monitor.
Các đim chính cn nh v phng thc notify()
Mt lung đa ra ngoài vùng đi ca monitor, và vào trng thái sn sàng.
Lung mà đã đc thông báo phi thu tr li khóa ca monitor trc khi nó có
th bt đu.
Phng thc notify() là không chính xác, nh là nó không th ch ra đc
lung mà phi đc thông báo. Trong mt trng thái đã trn ln, lung có th
thay đi trng thái ca monitor trong mt con đng mà không mang li kt
qu tt cho lung đã đc đa thông báo. Trong mt s trng hp này, các
phng thc ca monitor đa ra 2 s đ phòng:
o Trng thái ca monitor s đc kim tra trong mt vòng lp “while”
tt hn là câu lnh if
o Sau khi thay đi trng thái ca monitor, phng thc notifyAll() s
đc s dng, tt hn phng thc notify().
Chng trình 8.6 biu th cho vic s dng các phng thc notify(0 và wait():
Chng trình 8.6
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
/*<applet code = “mouseApplet” width = “100” height = “100”> </applet> */
public class mouseApplet extends Applet implements MouseListener{
boolean click;
int count;
public void init() {
super.init();
add(new clickArea(this)); //doi tuong ve duoc tao ra va them vao
add(new clickArea(this));//doi tuong ve duoc tao ra va them vao
addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
56
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
synchronized (this) {
click = true;
notify();
}
count++; //dem viec click
Thread.currentThread().yield();
click = false;
}
public void mouseReleased(MouseEvent e) {
}
} //kt thúc Applet
class clickArea extends java.awt.Canvas implements Runnable{
mouseApplet myapp;
clickArea(mouseApplet mapp){
this.myapp = mapp;
setSize(40,40);
new Thread(this).start();
}
public void paint(Graphics g){
g.drawString(new Integer(myapp.count).toString(),15,20);
}
public void run(){
while(true){
synchronized (myapp) {
while(!myapp.click){
try{
myapp.wait();
}catch(InterruptedException ie){
}
}
}
repaint(250);
}
}//end run
}
57
Không cn các phng thc wait() và notify(), lung bc v (canvas) không th
bit khi nào cp nhp hin th. Kt qu xut ra ngoài ca chng trình đc đa ra nh
sau:
Hình 8.8 Kt qu sau mi ln kích chut
12. S b tt (Deadlocks)
Mt “deadlock” (s b tt) xy ra khi hai lung có mt ph thuc vòng
quanh trên mt cp đi tng đng b; ly ví d, khi mt lung thâm nhp vào monitor
trên đi tng “ObjA”, và mt lung khác thâm nhp vào monitor trên đi tng “ObjB”.
Nu lung trong “ObjA” c gng gi phng thc đng b trên “ObjB”, mt b tt xy
ra.
Nó khó đ g li mt b tt bi nhng nguyên nhân sau:
Nó him khi xy ra, khi hai lung chia nh thi gian trong cùng mt con
đng
Nó có th bao hàm nhiu hn hai lung và hai đi tng đng b
Nu mt chng trình đa tuyn khóa kín thng xuyên, ngay lp tc kim tra li
điu kin b tt.
Chng trình 8.7 to ra điu kin b tt. Lp chính (main) bt đu 2 lung. Mi
lung gi phng thc đng b run(). Khi lung “t1” đánh thc, nó gi phng thc
“synchIt()” ca đi tng deadlock “dlk1”. T đó lung “t2” mt mình giám sát cho
“dlk2”, lung “t1” bt đu đi monitor. Khi lung “t2” đánh thc, nó c gng gi phng
thc “synchIt()” ca đi tng Deadlock “dlk2”. Bây gi, “t2” cng phi đi, bi vì đây
là trng hp tng t vi lung “t1”. T đó, c hai lung đang đi ln nhau, c hai s
đánh thc. ây là điu kin b tt.
Chng trình 8.7
public class Deadlock implements Runnable{
public static void main(String args[]){
Deadlock dlk1= new Deadlock();
Deadlock dlk2 = new Deadlock();
Thread t1 = new Thread(dlk1);
Thread t2 = new Thread(dlk2);
dlk1.grabIt = dlk1;
dlk2.grabIt = dlk2;
58
t1.start();
t2.start();
System.out.println("Started");
try{
t1.join();
t2.join();
}catch(InterruptedException e){
System.out.println("error occured");
}
System.exit(0);
}
Deadlock grabIt;
public synchronized void run() {
try{
Thread.sleep(1500);
}catch(InterruptedException e){
System.out.println("error occured");
}
grabIt.syncIt();
}
public synchronized void syncIt() {
try{
Thread.sleep(1500);
System.out.println("Sync");
}catch(InterruptedException e){
System.out.println("error occured");
}
System.out.println("In the syncIt() method");
}
}
Kt qu ca chng trình này đc hin th nh sau:
Hình 8.9 S b tt
59
13. Thu dn “rác” (Garbage collection)
Thu dn “rác” (Garbage collection) ci to hoc làm trng b nh đã đnh v cho
các đi tng mà các đi tng này không s dng trong thi gian dài. Trong ngôn ng
lp trình hng đi tng khác nh C++, lp trình viên phi làm cho b nh trng mà đã
không đc yêu cu trong thi gian dài. Tình trng không hot đng đ b nh trng có
th là kt qu trong mt s vn đ. Java t đng tin trình thu dn rác đ cung cp gii
pháp duy nht cho vn đ này. Mt đi tng tr nên thích hp cho s dn rác nu không
có tham chiu đn nó, hoc nu nó đã đng ký rng.
S dn rác thc thi nh là mt lung riêng bit có quyn u tiên thp. Bn có th
vin dn mt phng thc gc() ca th nghim đ vin dn s dn rác. Tuy nhiên, bn
không th d đoán hoc bo đm rng s dn rác s thc thi mt cách trn vn sau đó.
S dng câu ln sau đ tt đi s dn rác trong ng dng:
Java –noasyncgc ….
Nu chúng ta tt đi s dn rác, chng trình hu nh chc chn rng b treo do
bi vic đó.
1. Phng thc finalize() (hoàn thành)
Java cung cp mt con đng đ làm sch mt tin trình trc khi điu khin tr
li h điu hành. iu này tng t nh phng thc phân hy ca C++
Phng thc finalize(), nu hin din, s đc thc thi trên mi đi tng, trc
khi s dn rác.
Câu lnh ca phng thc finalize() nh sau:
protected void finalize() throws Throwable
Tham chiu không phi là s dn rác; ch các đi tng mi đc dn rác
Ly th nghim:
Object a = new Object();
Object b = a;
a = null;
đây, nó s sai khi nói rng “b” là mt đi tng. Nó ch là mt đi tng tham
chiu. Hn na, trong đon mã trích trên mc dù “a’ đc đt là rng, nó không th đc
dn rác, bi vì nó vn còn có mt tham chiu (b) đn nó. Vì th “a” vn còn vi đn
đc, tht vy, nó vn còn có phn vi s dng trong phm vi chng trình. đây, nó s
không đc dn rác.
Tuy nhiên, trong ví d cho di đây, gi đnh rng không có tham chiu đn “a”
tn ti, đi tng “a” tr nên thích hp cho garbage collection.
Object a = new Object();
…
…
…
a = null;
Mt ví d khác:
Object m = new Object();
Object m = null;
60
i tng đc to ra trong s bt đu có hiu lc cho garbage collection
Object m = new Object();
M = new Object();
Bây gi, đi tng cn nguyên có hiu lc cho garbage collection, và mt đi
tng mi tham chiu bi “m” đang tn ti.
Bn có th chy phng thc garbage collection, nhng không có ban đm rng
nó s xy ra.
Chng trình 8.8 đin hình cho garbage collection.
Chng trình 8.8
class GCDemo
{
public static void main(String args[])
{
int i;
long a; ,
Runtime r=Runtime.getRuntimeO;
Long valuesD =new Long[200];
System. out. print In ("Amount of free memory is" +
r.freeMemoryO);
r.gcO;
System.out.println("Amount of free memory after garbage
collection is " + r.freeMemoryO);
for (a=IOOOO.i=O;i<200;a++.i++)
{
values[i] =new Long(a);
}
System.out.println("Amount of free memory after creating the array
" + r.freeMemoryO);
for (i=O;i<200;i++)
{
values[i] =null;
}
System.out.println("Arnount of free memory after garbage collection is
" + r.freeMemoryO);
}
Chúng ta khai mt mng gm 200 phn t, trong đó kiu d liu là kiu Long.
Trc khi mng đc to ra, chúng ta phi xác đnh rõ s lng b nh trng, và hin th
nó. Ri thì chúng ta vin dn phng thc gc() ca th nghim Runtime (thi gian thc
thi) hin thi. iu này có th hoc không th thc thi garbage collection. Ri thì chúng
ta to ra mng, và đang ký giá tr cho các phn t ca mng. iu này s gim bt s
lng b nh trng. làm các mng phn t thích hp cho garbage collection, chúng ta
đt chúng rng. Cui cùng, chúng ta s dng phng thc gc() đ vin dn garbage
collection ln na.
Kt qu xut ra màn hình ca chng trình trên nh sau:
61
Hình 8.10 Garbage collection
Tng kt
Mt lung là đn v nh nht ca đon mã thc thi đc mà mt tác v riêng
bit.
a tuyn gi cho thi gian ri là nh nht. iu này cho phép bn vit các
chng trình có kh nng s dng ti đa CPU.
Lung bt đu thc thi sau khi phng thc start() đc gi
Lp trình viên, máy o Java, hoc h điu hành bo đm rng CPU đc chia
s gia các lung.
Có hai loi lung trong mt chng trình Java:
o Lung ngi dùng
o Lung him.
Mt nhóm lung là mt lp mà nm bt mt nhóm các lung.
ng b cho phép ch mt lung thâm nhp mt tài nguyên đc chia s ti
mt thi đim.
tránh kim soát vòng, Java bao gm mt thit k tt trong tin trình k
thut truyn thông s dng các phng thc “wait()” (đi), “notify()” (thông
báo) và “notifyAll()” (thông báo ht).
Mt “b tt” xy ra khi hai lung có mt ph thuc xoay vòng trên mt phn
ca các đi tng đng b
Garbage collection là mt tin trình nh đó b nh đc đnh v đ các đi
tng mà không s dng trong thi gian dài, có th ci to hoc làm rãnh b
nh.
Kim tra li s hiu bit ca bn
1. Mt ng dng có th cha đng nhiu lung úng/Sai
2. Các lung con đc to ra t lung chính úng/Sai
3. Mi lung trong mt chng trình Java đc đng ký mt quyn u tiên mà máy
o Java có th thay đi. úng/Sai
62
4. Phng thc____________ có th tm thi ngng vic thc thi lung
5. Mc đnh, mt lung có mt quyn u tiên ________ mt hng s ca _______
6. _________ lung đc dùng cho các lung “nn”, cung cp dch v cho lung
khác.
7. Trong lung đng b, mt __________ là mt đi tng mà đc s dng nh là
mt khóa riêng bit ln nhau.
8. ___________ thng thc thi bi mt vòng lp mà đc s dng đ lp li vic
kim tra mt s điu kin.
Bài tp:
1. Vit mt chng trình mà hin th mt s đm lùi tng giây cho đn không, nh
hình sau:
Ban đu, s 300 s đc hin th. Giá tr s đc gim dn cho đn 1 đn khi
ngoài giá tr 0. Giá tr s đc tr li 300 mt ln na gim đn tr thành 0.
63
2. Vit mt chng trình mà hin th nh hình di đây:
To 3 lung và mt lung chính trong “main”. Thc thi mi lung nh mt
chng trình thc thi. Khi chng trình kt thúc, các câu lnh thoát cho mi lung s
đc hin th. S dng k thut nm bt li.