1. Trang chủ
  2. » Công Nghệ Thông Tin

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

23 217 0

Đ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

Thông tin cơ bản

Định dạng
Số trang 23
Dung lượng 380,32 KB

Nội dung

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

w