Tài liệu Java : Đa tuyến pptx

23 216 0
Tài liệu Java : Đa tuyến pptx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

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] N hó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. 50 Chng 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++); [...]... ng th c c a monitor a ra 2 s phòng: o Tr ng thái c a monitor s c ki m tra trong m t vòng l p “while” t t h n là câu l nh if o Sau khi thay i tr ng thái c a monitor, ph ng th c notifyAll() s c s d ng, t t h n ph ng th c notify() Ch ng trình 8.6 bi u th cho vi c s d ng các ph ng th c notify(0 và wait( ): Ch ng trình 8.6 import java. applet.*; import java. awt.*; import java. awt.event.*; /* . nh trong khi s dng phng thc wait( ):  Lung đang gi đa vào CPU  Lung đang gi đa vào khóa  Lung đang gi đi vào vùng đi ca monitor. . dng các phng thc notify(0 và wait( ): Chng trình 8.6 import java. applet.*; import java. awt.*; import java. awt.event.*; /*<applet code =

Ngày đăng: 19/01/2014, 16:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan