Tải bản đầy đủ (.pdf) (23 trang)

Tài liệu JAVA-8 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (380.32 KB, 23 trang )

41
A TUYN
Mc tiêu:
Sau khi kt thúc ching này, bn có th:
 nh ngha mt lung
 Mô t đa tuyn
 To và qun lý lung
 Hiu đc vòng đi ca lung
 Mô t mt lung him
 Gii thích tp hp các lung u tiên nh th nào
 Gii thích đc s cn thit ca s đng b
 Hiu đc cách thêm vào các t khoá synchronized (đng b) nh th
nào
 Lit kê nhng điu không thun li ca s đng b
 Gii thích vai trò ca các phng thc wait() (đi), notify() (thông
báo) và notifyAll().
 Mô t mt điu kin b tc (deadlock).
1. Gii thiu
Mt lung là mt thuc tính duy nht ca Java. Nó là đn v nh nht ca đon
mã có th thi hành đc mà thc hin mt công vic riêng bit. Ngôn ng Java và máy o
Java c hai là các h thng đc phân lung
2. a tuyn
Java h tr đa tuyn, mà có kh nng làm vic vi nhiu lung. Mt ng dng có
th bao hàm nhiu lung. Mi lung đc đng ký mt công vic riêng bit, mà chúng
đc thc thi đng thi vi các lung khác.
a tuyn gi thi gian nhàn ri ca h thng thành nh nht. iu này cho phép
bn vit các chng trình có hiu qu cao vi s tn dng CPU là ti đa. Mi phn ca
chng trình đc gi mt lung, mi lung đnh ngha mt đng dn khác nhau ca s
thc hin. ây là mt thit k chuyên dùng ca s đa nhim.
Trong s đa nhim, nhiu chng chng trình chy đng thi, mi chng trình
có ít nht mt lung trong nó. Mt vi x lý thc thi tt c các chng trình. Cho dù nó có


th xut hin mà các chng trình đã đc thc thi đng thi, trên thc t b vi x lý
nhy qua li gia các tin trình.
3. To và qun lý lung
Khi các chng trình Java đc thc thi, lung chính luôn luôn đang đc thc
hin. ây là 2 nguyên nhân quan trng đi vi lung chính:
 Các lung con s đc to ra t nó.
 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.
Cho dù lung chính đc to ra mt cách t đng vi chng trình thc thi, nó có
th đc điu khin thông qua mt lung đi tng.
Các lung có th đc to ra t hai con đng:
 Trình bày lp nh là mt lp con ca lp lung, ni mà phng thc run() ca
lp lung cn đc ghi đè. Ly ví d:
42
Class Mydemo extends Thread
{
//Class definition
public void run()
{
//thc thi
}
}
 Trình bày mt lp mà lp này thc hin lp Runnable. Ri thì đnh ngha
phng thc run().
Class Mydemo implements Runnable
{
//Class definition
public void run()
{
//thc thi

}
}
Chng trình 8.1 s ch ra s điu khin lung chính nh th nào
Chng 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 kt qu xut ra màn hình ca chng trình trên
43

Hình 8.1 Lung
Trong kt qu xut ra  trên










Mi lung trong chng trình Java đc đng ký cho mt quyn u tiên. Máy o
Java không bao gi thay đi quyn u tiên ca lung. Quyn u tiên vn còn là hng s
cho đn khi lung b ngt.
Mi lung có mt giá tr u tiên nm trong khong ca mt
Thread.MIN_PRIORITY ca 1, và mt Thread.MAX_PRIORITY ca 10. Mi lung ph
thuc vào mt nhóm lung, và mi nhóm lung có quyn u tiên ca chính nó. Mi
lung đc nhn mt hng s u tiên ca phng thc Thread.PRIORITY là 5. Mi
lung mi tha k quyn u tiên ca lung mà to ra nó.
Lp lung có vài phng thc khi dng, hai trong s các phng thc khi
dng đc đ cp đn di đây:
 public Thread(String threadname)
Cu trúc mt lung vi tên là “threadname”
 public Thread()
Cu trúc mt lung vi tên “Thread, đc ràng buc vi mt s; ly ví d,
Thread-1, Thread-2, v.v…
Chng trình bt đu thc thi lung vi vic gi phng thc start(), mà phng
thc này ph thuc vào lp lung. Phng thc này, ln lt, vin dn phng thc
run(), ni mà phng thc đnh ngha tác v đc thc thi. Phng thc này có th vit
đè lên lp con ca lp lung, hoc vi mt đi tng Runnable.
4. Vòng đi ca Lung

[main, 5 , main]

Nhóm lung mà nó ph thuc vào
Quyn u tiên đc đt bi JVM
Tên ca lung
44

Hình 8.3 Vòng đi ca lung
5. Phm vi ca lung và các phng thc ca lp lung
Mt lung đã đc to mi gn đây là trong phm vi “sinh”. Lung không bt
đu chy ngay lp tc sau khi nó đc to ra. Nó đi phng thc start() ca chính nó
đc gi. Cho đn khi, nó là trong phm vi “sn sàng đ chy”. Lung đi vào phm vi
“đang chay” khi h thng đnh rõ v trí lung trong b vi x lý.
Bn có th s dng phng thc sleep() đ tm thi treo s thc thi ca lung.
Lung tr thành sn sàng sau khi phng thc sleep kt thúc thi gian. Lung Sleeping
không s dng b vi x lý. lung đi vào phm vi “waiting” (đi) khi mt lung đang
chy gi phng thc wait() (đi).
Khi các lung khác liên kt vi các đi tng, gi phng thc notify(), lung đi
vào tr li phm vi “ready” (sn sàng) Lung đi vào phm vi “blocked” (khi) khi nó
đang thc thi các phép toán vào/ra (Input/output). Nó đi vào phm vi “ready” (sn sàng)
khi các phng thc vào/ra nó đang đi cho đn khi đc hoàn thành. Lung đi vào
phm vi “dead” (cht) sau khi phng thc run() đã đc thc thi hoàn toàn, hoc khi
phng thc stop() (dng) ca nó đc gi.
Thêm vào các phng thc đã đc đ cp trên, Lp lung cng có các phng
thc sau:
Phng thc Mc đích
Enumerate(Thread t) Sao chép tt c các lung hin hành vào mng đc ch
đnh t nhóm ca các lung, và các nhóm con ca nó.
getName() Tr v tên ca lung
isAlive() Tr v úng, nu lung là vn còn tn ti (sng)
getPriority() Tr v quyn u tiên ca lung
setName(String name) t tên ca lung là tên mà lung đc truyn nh là

mt tham s.
join() i cho đn khi lung cht.
isDaemon(Boolean on) Kim tra nu lung là lung mt lung him.
resume() ánh du lung nh là lung him hoc lung ngi s
dng ph thuc vào giá tr đc truyn vào.
sleep() Hoãn lung mt khoáng thi gian chính xác.
start() Gi phng thc run() đ bt đu mt lung.
45
Bng 8.1 Các phng thc ca mt lp lung
Bng k hoch Round-robin (bng kin ngh ký tên vòng tròn) liên quan đn các
lung vi cùng quyn u tiên đc chim hu quyn u tiên ca mi lung khác. Chúng
chia nh thi gian mt cách t đng trong theo kiu k hoch xoay vòng này.
Phiên bn mi nht ca Java không h tr các phng thc Thread.suspend() (trì
hoãn), Thread.resume() (phc hi) và Thread.stop() (dng), nh là các phng thc
resume() (phc hi) và suspend() (trì hoãn) đc thiên v s đình tr (deadlock), trong
khi phng thc stop() không an toàn.
6. Thi gian biu lung
Hu ht các chng trình Java làm vic vi nhiu lung. CPU cha đng cho vic
chy chng trình ch mt lung ti mt khong thi gian. Hai lung có cùng quyn u
tiên trong mt chng trình hoàn thành trong mt thi gian CPU. Lp trình viên, hoc
máy o Java, hoc h điu hành chc chn rng CPU đc chia s gia các lung. iu
này đc bit nh là bng thi gian biu lung.
Không có máy o Java nào thc thi rành mch cho bng thi gian biu lung. Mt
s nn Java h tr vic chia nh thi gian.  đây, mi lung nhn mt phn nh ca thi
gian b vi x lý, đc gi là đnh lng. Lung có th thc thi tác v ca chính nó trong
sut khong thi gian đnh lng đy. Sau khong thi gian này đc vt qua, lung
không đc nhn nhiu thi gian đ tip tc thc hin, ngay c nu nó không đc hoàn
thành vic thc hin ca nó. Lung k tip ca lung có quyn u tiên bng nhau này s
ly khong thi gian thay đi ca b vi x lý. Java là ngi lp thi gian biu chia nh tt
c các lung có cùng quyn u tiên cao.

Phng thc setPriority() ly mt s nguyên (integer) nh là mt tham s có th
hiu chnh quyn u tiên ca mt lung. ây là giá tr có phm vi thay đi t 1 đn 10,
mc khác, phng thc đa ra mt ngoi l (by li) đc gi là
IllegalArgumentException (Chp nhn tham s trái lut)
Phng thc yield() (li nhun) đa ra các lung khác mt kh nng đ thc thi.
Phng thc này đc thích hp cho các h thng không chia nh thi gian (non-time-
sliced), ni mà các lung hin thi hoàn thành vic thc hin trc khi các lung có
quyn u tiên ngang nhau k tip tip qun.  đây, bn s gi phng thc yield() ti
nhng khon thi gian riêng bit đ có th tt c các lung có quyn u tiên ngang nhau
chia s thi gian thc thi CPU.
Chng trình 8.2 chng minh quyn u tiên ca lung:
Chng 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());
}
}
}

}

Kt qu hin th nh hình 8.4

Hình 8.4 Quyn u tiên lung
7. Lung him
Mt chng trình Java b ngt ch sau khi tt c các lung b cht. Có hai kiu
lung trong mt chng trình Java:
 Các lung ngi s dng
 Lung him
Ngi s dng to ra các lung ngi s dng, trong khi các lung đc ch đnh
nh là lung “background” (nn). Lung him cung cp các dch v cho các lung khác.
Máy o Java thc hin tin trình thoát, khi và ch khi lung him vn còn sng. Máy o
47
Java có ít nht mt lung him đc bit đn nh là lung “garbage collection” (thu

lm nhng d liu vô ngha - dn rác). Lung dn rác thc thi ch khi h thng không
có tác v nào. Nó là mt lung có quyn u tiên thp. Lp lung có hai phng thc đ
tha thun vi các lung him:
 public void setDaemon(boolean on)
 public boolean isDaemon()
8. a tuyn vi Applets
Trong khi đa tuyn là rt hu dng trong các chng trình ng dng đc lp, nó
cng đáng đc quan tâm vi các ng dng trên Web. a tuyn đc s dng trên web,
cho ví d, trong các trò chi đa phng tin, các bc nh đy sinh khí, hin th các dòng
ch chy qua li trên biu ng, hin th đng h thi gian nh là mt phn ca trang Web
v.vv… Các chc nng này cu thành các trang web làm quyn r và bt mt.
Chng trình Java da trên Applet thng s dng nhiu hn mt lung. Trong
đa tuyn vi Applet, lp java.applet.Applet là lp con đc to ra bi ngi s dng đnh
ngha applet. T đó, Java không h tr nhiu k tha vi các lp, nó không th thc hin
đc trc tip lp con ca lp lung trong các applet. Tuy nhiên, chúng ta s dng mt
đi tng ca lung ngi s dng đã đnh ngha, mà các lung này, ln lt, dn xut t
lp lung. Mt lung đn gin xut hin s đc thc thi ti giao din (Interface)
Runnable
Chng trình 8.3 ch ra điu này thc thi nh th nào:
Chng 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 chng trình này, chúng ta to ra mt Applet đc gi là Myapplet, và
thc thi giao din Runnable đ cung cp kh nng đa tuyn cho applet. Sau đó, chúng ta
to ra mt th nghim (instance) cho lp lung, vi th nghim applet hin thi nh là
mt tham s đ thit lp (khi dng). Ri thì chúng ta vin dn phng thc start() ca
lung th nghim này. Ln lt, ri s vin dn phng thc run(), mà phng thc này
thc s là đim bt đu cho phng thc này. Chúng ta in s t 1 đn 20 vi thi gian
kéo tr là 500 miligiây gia mi s. Phng thc sleep() đc gi đ hoàn thành thi
gian kéo tr này. ây là mt phng thc tnh đc đnh ngha trong lp lung. Nó cho
phép lung nm yên (ng) trong khon thi gian hn ch.
Xut ra ngoài có dng nh sau:

Hình 8.5 a tuyn vi Applet

9. Nhóm lung
Mt lp nhóm lung (ThreadGroup) nm bt mt nhóm ca các lung. Ly ví d,
mt nhóm lung trong mt trình duyt có th qun lý tt c các lung ph thuc vào mt
đn th applet. Tt c các lung trong máy o Java ph thuc vào các nhóm lung mc
đnh. Mi nhóm lung có mt nhóm ngun cha. Vì th, các nhóm t mt cu trúc dng
cây. Nhóm lung “h thng” là gc ca tt c các nhóm lung. Mt nhóm lung có th là
thành phn ca c các lung, và các nhóm lung.
Hai kiu nhóm lung thit lp (khi dng) là:
 public ThreadGroup(String str)
 đây, “str” là tên ca nhóm lung mi nht đc to ra.
 public ThreadGroup(ThreadGroup tgroup, String str)
 đây, “tgroup” ch ra lung đang chy hin thi nh là lung cha, “str” là tên ca
nhóm lung đang đc to ra.
Mt s các phng thc trong nhóm lung (ThreadGroup) đc cho nh sau:
 public synchronized int activeCount()
49
Tr v s lng các lung kích hot hin hành trong nhóm lung
 public sunchronized int activeGroupCount()
Tr v s lng các nhóm hot đng trong nhóm lung
 public final String getName()
Tr v tên ca nhóm lung
 public final ThreadGroup getParent()
Tr v cha ca nhóm lung
10. S đng b lung
Trong khi đang làm vic vi nhiu lung, nhiu hn mt lung có th mun thâm
nhp cùng bin ti cùng thi đim. Ly ví d, mt lung có th c gng đc d liu, trong
khi lung khác c gng thay đi d liu. Trong trng hp này, d liu có th b sai lc.
Trong nhng trng hp này, bn cn cho phép mt lung hoàn thành trn vn
tác v ca nó (thay đi giá tr), và ri thì cho phép các lung k tip thc thi. Khi hai
hoc nhiu hn các lung cn thâm nhp đn mt tài nguyên đc chia s, bn cn chc

chn rng tài nguyên đó s đc s dng ch bi mt lung ti mt thi đim. Tin trình
này đc gi là “s đng b” (synchronization) đc s dng đ lu tr cho vn đ này,
Java cung cp duy nht, ngôn ng cp cao h tr cho s đng b này. Phng thc “đng
b” (synchronized) báo cho h thng đt mt khóa vòng mt tài nguyên riêng bit.
Mu cht ca s đng b hóa là khái nim “monitor” (s quan sát, giám sát),
cng đc bit nh là mt bng mã “semaphore” (bng mã). Mt “monitor” là mt đi
tng mà đc s dng nh là mt khóa qua li duy nht, hoc “mutex”. Ch mt lung
có th có riêng nó mt s quan sát (monitor) ti mi thi đim đc đa ra. Tt c các
lung khác c gng thâm nhp vào monitor b khóa s b trì hoãn, cho đn khi lung đu
tiên thoát khi monitor. Các lung khác đc báo ch đi monitor. Mt lung mà
monitor ca riêng nó có th thâm nhp tr li cùng monitor.
1. Mã đng b
Tt c các đi tng trong Java đc liên kt vi các monitor (s giám sát) ca
riêng nó.  đng nhp vào monitor ca mt đi tng, lp trình viên s dng t khóa
synchronized (đng b) đ gi mt phng thc hiu chnh (modified). Khi mt lung
đang đc thc thi trong phm vi mt phng thc đng b (synchronized), bt k lung
khác hoc phng thc đng b khác mà c gng gi nó trong cùng th nghim s phi
đi.
Chng trình 8.4 chng minh s làm vic ca t khóa synchronized (s đng b).
 đây, lp “Target” (mc tiêu) có mt phng thc “display()” (hin th) mà phng
thc này ly mt tham s kiu s nguyên (int). S này đc hin th trong phm vi các
cp ký t “< > # s # <>”. Phng thc “Thread.sleep(1000) tm dng lung hin ti sau
khi phng thc “display()” đc gi.
Thit lp (khi dng) ca lip “Source” ly mt tham chiu đn mt đi tng “t”
ca lp “Target”, và mt bin s nguyên (integer).  đây, mt lung mi cng đc to
ra. Lung này gi phng thc run() ca đi tng “t”. Lp chính “Synch” th nghim
lp “Target” nh là “target (mc tiêu), và to ra 3 đi tng ca lp “Source” (ngun).
Cùng đi tng “target” đc truyn cho mi đi tng “Source”. Phng thc “join()”
(gia nhp) làm lung đc gi đi cho đn khi vic gi lung b ngt.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×