Multithreading – vícevláknovosthunka/vyuka/javaOOP/obop2/jvcv09/Threads.pdf · • Java má...
Transcript of Multithreading – vícevláknovosthunka/vyuka/javaOOP/obop2/jvcv09/Threads.pdf · • Java má...
1
Multithreading – vícevláknovost
• aktivní objekty a jejich životní pravidla
• práce s vlákny
• prostředky pro paralelní programování
• vlákna – podprocesy, sdílejí datové zdroje
• s konkurentností (souběžností) se setkáváme v API – specifikaci - aplikace obsahuje běhovávlákna, kde každé vlákno určuje část programu, který může běžet souběžně s ostatními vlákny
2
Obsah p řednášky
1. Úvod
2. Vlákno
3. Implementace vlákna
4. Vlákna uživatele a démoni
5. Priority vláken, plánování běhu vláken
6. Stavy vláken
7. Metoda jion()
8. Synchronizace vláken
9. Komunikace mezi vlákny
10. Deadlock uváznutí
3
1 Úvod
• Concurrency (souběžnost) - normálně dostupná v primitivních operacích operačního systému
• Java má podporu pro vícevláknové zpracovánízabudovanou v sobě (provides built-in multithreading)– Multithreading zlepšuje výkonnost některých programů
např. browserů a těch, kde je souběžnost implicitní
– Úlohy na prohledávání, vykreslování mohou využít svůj implicitní charakter souběžnosti
4Procesy & vlákna
Kód Data
Status procesuZdroje
Abstraktní prost ředí stroje (OS)
Proces
5
Procesy & vlákna
Data
Status vlákna
Vlákna
DataText programu
Status procesuZdroje
Heavyweight process
lightweight processes
6
2 Vlákno - thread
• Vlákno je podobné sekvenčním programům
• Samotné vlákno není program; nemůže běžet samo o sobě; vlákno spíše běží uvnitř programu
• Vlákno je jeden sekvenční tok řízení v kontextu programu
• Hlavní využití vláken není v použití jednoho sekvenčního vlákna, ale ve využití více vláken běžících ve stejném čase, vykonávající různéúlohy daného programu.
7
Program - vlákno
ProgramVlákno
Vlákno spuštěné v kontextu programu
Dvě vlákna
Dvě vlákna současně spuštěná v kontextu jednoho programu
Program
8
Vlákno
• Někdy se vlákna proto nazývajílightweightprocess a procesy (heavyweight process)
• Vlákno je podobné procesu reálného světa – májeden sekvenční tok řízení
• Avšak – vlákno se nazýválightweight, protože „běží“ uvnitř kontextu programu a využívávýhody, že zdroje jsou přiděleny programu a jeho prostředí.
• Vlákno si musí pro sebe získat některé zdroje uvnitř běžícího programu.
9
Vlákno
• Vlákno má vlastnízásobník běhu (execution stack) a čítač programu(program counter)
• Kód prováděný ve vlákně funguje pouze tomto kontextu (kontextu programu).
• Program má vždy alespoň jedno vlákno, to jedno začíná od metody main(). (main vlákno)
• Když program vytvoří vlákno, je toto nové vlákno vytvořeno navíc k vláknu, které jej vytvořilo.
• Každé další vytvořené vlákno (mimo implicitnívlákno main) je představováno objektem třídy Thread, balíčku java.lang.Thread.
Osnova10
Jednoduchý příklad – subclassing(dědičnost)
import import import import java.io.IOExceptionjava.io.IOExceptionjava.io.IOExceptionjava.io.IOException;;;;
public class public class public class public class TryThreadTryThreadTryThreadTryThread extends Threadextends Threadextends Threadextends Thread {{{{
private String private String private String private String firstNamefirstNamefirstNamefirstName; // Store for first name; // Store for first name; // Store for first name; // Store for first name
private String private String private String private String secondNamesecondNamesecondNamesecondName; // Store for second name; // Store for second name; // Store for second name; // Store for second name
private long private long private long private long aWhileaWhileaWhileaWhile; // Delay in milliseconds; // Delay in milliseconds; // Delay in milliseconds; // Delay in milliseconds
// konstruktor// konstruktor// konstruktor// konstruktor
public public public public TryThread(StringTryThread(StringTryThread(StringTryThread(String firstNamefirstNamefirstNamefirstName, String , String , String , String secondNamesecondNamesecondNamesecondName, long delay), long delay), long delay), long delay)
{{{{
this.firstNamethis.firstNamethis.firstNamethis.firstName = = = = firstNamefirstNamefirstNamefirstName; // Store the first name; // Store the first name; // Store the first name; // Store the first name
this.secondNamethis.secondNamethis.secondNamethis.secondName = = = = secondNamesecondNamesecondNamesecondName; // Store the second name; // Store the second name; // Store the second name; // Store the second name
aWhileaWhileaWhileaWhile = delay; // Store the delay= delay; // Store the delay= delay; // Store the delay= delay; // Store the delay
setDaemon(truesetDaemon(truesetDaemon(truesetDaemon(true); ); ); ); // Thread is daemon// Thread is daemon// Thread is daemon// Thread is daemon
}}}}
public static void public static void public static void public static void main(Stringmain(Stringmain(Stringmain(String[] [] [] [] argsargsargsargs))))
{{{{
// Create three threads// Create three threads// Create three threads// Create three threads
Thread first = new Thread first = new Thread first = new Thread first = new TryThread("HopalongTryThread("HopalongTryThread("HopalongTryThread("Hopalong ", "Cassidy ", 200L);", "Cassidy ", 200L);", "Cassidy ", 200L);", "Cassidy ", 200L);
Thread second = new Thread second = new Thread second = new Thread second = new TryThread("MarilynTryThread("MarilynTryThread("MarilynTryThread("Marilyn ", "Monroe ", 300L);", "Monroe ", 300L);", "Monroe ", 300L);", "Monroe ", 300L);
Thread third = new Thread third = new Thread third = new Thread third = new TryThread("SlimTryThread("SlimTryThread("SlimTryThread("Slim ", "Pickens ", 500L);", "Pickens ", 500L);", "Pickens ", 500L);", "Pickens ", 500L);
System.out.println("PressSystem.out.println("PressSystem.out.println("PressSystem.out.println("Press Enter when you have had enough...Enter when you have had enough...Enter when you have had enough...Enter when you have had enough...\\\\n");n");n");n");
first.startfirst.startfirst.startfirst.start(); (); (); (); // Start the first thread// Start the first thread// Start the first thread// Start the first thread
second.startsecond.startsecond.startsecond.start(); (); (); (); // Start the second thread// Start the second thread// Start the second thread// Start the second thread
third.startthird.startthird.startthird.start(); (); (); (); // Start the third thread// Start the third thread// Start the third thread// Start the third thread
Osnova11
sleep() – uvolníprocesor, ale neuvolní objekty, které jsou aktuálním vláknem uzamknuty
trytrytrytry {{{{
System.in.System.in.System.in.System.in.readreadreadread();();();(); // Wait // Wait // Wait // Wait untiluntiluntiluntil EnterEnterEnterEnter keykeykeykey pressedpressedpressedpressed
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln("("("("EnterEnterEnterEnter pressedpressedpressedpressed............\\\\n");n");n");n");
} } } }
catchcatchcatchcatch ((((IOExceptionIOExceptionIOExceptionIOException e) // Handle IO e) // Handle IO e) // Handle IO e) // Handle IO exceptionexceptionexceptionexception
{{{{
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln(e); // (e); // (e); // (e); // OutputOutputOutputOutput thethethethe exceptionexceptionexceptionexception
}}}}
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln("("("("EndingEndingEndingEnding mainmainmainmain()");()");()");()");
returnreturnreturnreturn;;;;
}}}}
// // // // MethodMethodMethodMethod wherewherewherewhere threadthreadthreadthread executionexecutionexecutionexecution willwillwillwill startstartstartstart
public public public public voidvoidvoidvoid run() {run() {run() {run() {
trytrytrytry {{{{
whilewhilewhilewhile((((truetruetruetrue ) // ) // ) // ) // LoopLoopLoopLoop indefinitelyindefinitelyindefinitelyindefinitely............
{{{{
SystemSystemSystemSystem....outoutoutout....printprintprintprint((((firstNamefirstNamefirstNamefirstName); // ); // ); // ); // OutputOutputOutputOutput firstfirstfirstfirst namenamenamename
sleepsleepsleepsleep((((aWhileaWhileaWhileaWhile); // Wait ); // Wait ); // Wait ); // Wait aWhileaWhileaWhileaWhile msecmsecmsecmsec....
SystemSystemSystemSystem....outoutoutout....printprintprintprint((((secondNamesecondNamesecondNamesecondName + "+ "+ "+ "\\\\n"); // n"); // n"); // n"); // OutputOutputOutputOutput secondsecondsecondsecond namenamenamename
}}}}
}}}}
catchcatchcatchcatch((((InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e) // Handle e) // Handle e) // Handle e) // Handle threadthreadthreadthread interruptioninterruptioninterruptioninterruption
{{{{
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln((((firstNamefirstNamefirstNamefirstName + + + + secondNamesecondNamesecondNamesecondName + e); + e); + e); + e);
// // // // OutputOutputOutputOutput thethethethe exceptionexceptionexceptionexception
}}}}
}}}}
}}}}
Osnova12
Press Enter when you have had enough...Press Enter when you have had enough...Press Enter when you have had enough...Press Enter when you have had enough...
HopalongHopalongHopalongHopalong Marilyn Marilyn Marilyn Marilyn
Slim Cassidy Slim Cassidy Slim Cassidy Slim Cassidy
HopalongHopalongHopalongHopalong Monroe Monroe Monroe Monroe
Marilyn Cassidy Marilyn Cassidy Marilyn Cassidy Marilyn Cassidy
HopalongHopalongHopalongHopalong Pickens Pickens Pickens Pickens
Slim Cassidy Slim Cassidy Slim Cassidy Slim Cassidy
HopalongHopalongHopalongHopalong Monroe Monroe Monroe Monroe
Marilyn Cassidy Marilyn Cassidy Marilyn Cassidy Marilyn Cassidy
HopalongHopalongHopalongHopalong Monroe Monroe Monroe Monroe
Marilyn Pickens Marilyn Pickens Marilyn Pickens Marilyn Pickens
Slim Cassidy Slim Cassidy Slim Cassidy Slim Cassidy
HopalongHopalongHopalongHopalong Cassidy Cassidy Cassidy Cassidy
HopalongHopalongHopalongHopalong Monroe Monroe Monroe Monroe
Marilyn Marilyn Marilyn Marilyn
Enter pressed...Enter pressed...Enter pressed...Enter pressed...
Ending main()Ending main()Ending main()Ending main()
13Jednoduchý p říkladimplementace rozhraní Runnable
• vlákno main načte počet opakování zadaný uživatelem
• hlavní program (vlákno main) vytvoří instanci theApp, která vykoná metodu doIt()
• v metodě doIt se vytvoří vlákno na které odkazuje proměnnát
Thread first = new Thread(“Jak”,”se”,45L);
Thread t = new Thread(this);
• v prvém případě - defaultní běhuschopný cíl
• ve druhém odkazuje na třídu, jejíž objekt implementoval metodu run()
Osnova14
Výsledky aplikace:
Prvni vlaknoDruhe vlaknoPrvni vlaknoDruhe vlaknoPrvni vlaknoDruhe vlakno
Na různých JVM -různé
classclassclassclass ThreadEx1 ThreadEx1 ThreadEx1 ThreadEx1 implementsimplementsimplementsimplements RunnableRunnableRunnableRunnable {{{{
private static private static private static private static intintintint howManyhowManyhowManyhowMany;;;;
private private private private voidvoidvoidvoid doItdoItdoItdoIt() {() {() {() {
ThreadThreadThreadThread t = t = t = t = newnewnewnew ThreadThreadThreadThread( ( ( ( thisthisthisthis ););););
t.start(); //*** startuje nove t.start(); //*** startuje nove t.start(); //*** startuje nove t.start(); //*** startuje nove vytvorenevytvorenevytvorenevytvorene vlaknovlaknovlaknovlakno
forforforfor ( ( ( ( intintintint i = 0; i < i = 0; i < i = 0; i < i = 0; i < howManyhowManyhowManyhowMany; i++ ); i++ ); i++ ); i++ )
System.System.System.System.outoutoutout....printlnprintlnprintlnprintln( "( "( "( "Prvni Prvni Prvni Prvni vlaknovlaknovlaknovlakno" );" );" );" );
}}}}
public public public public voidvoidvoidvoid run() {run() {run() {run() { //*** implementace metody run()//*** implementace metody run()//*** implementace metody run()//*** implementace metody run()
forforforfor ( ( ( ( intintintint i = 0; i < i = 0; i < i = 0; i < i = 0; i < howManyhowManyhowManyhowMany; i++ ); i++ ); i++ ); i++ )
System.System.System.System.outoutoutout....printlnprintlnprintlnprintln( "( "( "( "Druhe Druhe Druhe Druhe vlaknovlaknovlaknovlakno" );" );" );" );
} } } } //*** t se //*** t se //*** t se //*** t se zastavizastavizastavizastavi, kdy, kdy, kdy, kdyžžžž se dostane na konec run()se dostane na konec run()se dostane na konec run()se dostane na konec run()
public static public static public static public static voidvoidvoidvoid mainmainmainmain( ( ( ( StringStringStringString[ ] [ ] [ ] [ ] argsargsargsargs ) ) ) ) throwsthrowsthrowsthrows ExceptionExceptionExceptionException {{{{
ifififif ( ( ( ( argsargsargsargs....lengthlengthlengthlength < 1 ) < 1 ) < 1 ) < 1 )
throwthrowthrowthrow newnewnewnew ExceptionExceptionExceptionException( ( ( (
""""\\\\nnnn\\\\nInvokenInvokenInvokenInvoke as: ThreadEx1 <as: ThreadEx1 <as: ThreadEx1 <as: ThreadEx1 <howhowhowhow many many many many iterationsiterationsiterationsiterations>>>>\\\\n" );n" );n" );n" );
howManyhowManyhowManyhowMany = = = = newnewnewnew IntegerIntegerIntegerInteger( ( ( ( argsargsargsargs[ 0 ] ).[ 0 ] ).[ 0 ] ).[ 0 ] ).intValueintValueintValueintValue();();();();
ThreadEx1 ThreadEx1 ThreadEx1 ThreadEx1 theApptheApptheApptheApp = = = = newnewnewnew ThreadEx1();ThreadEx1();ThreadEx1();ThreadEx1();
theApptheApptheApptheApp....doItdoItdoItdoIt();();();();
} //*** } //*** } //*** } //*** mainmainmainmain ThreadThreadThreadThread stopsstopsstopsstops whenwhenwhenwhen mainmainmainmain exitsexitsexitsexits
}}}}
15
Vysv ětlení
• běhuschopný cíl (runnable target) – objekt, jehožtřída implementuje metodu run()
• theApp – je pouze instance vytvořená vláknem main
• this a theApp – se odkazují na stejný objekt třídy ThreadEx1
16
Zastavení vláken
• zastavení vláken se provede prostřednictvím instanční metody interrupted()
• metoda pouze signalizuje vláknu, že je přerušené –vlákno pokračuje ve svéčinnosti dále.
• kontrola příznaku se provádí např. v metoděsleep(). Metoda sleep() kontroluje, zda bylo vlákno přerušeno a pokud ano, vyvolá výjimku typu InterruptedException.
Osnova17
import import import import java.io.IOExceptionjava.io.IOExceptionjava.io.IOExceptionjava.io.IOException;;;;
public class TryThread1 extends Threadpublic class TryThread1 extends Threadpublic class TryThread1 extends Threadpublic class TryThread1 extends Thread
{{{{
private String private String private String private String firstNamefirstNamefirstNamefirstName; // Store for first name; // Store for first name; // Store for first name; // Store for first name
private String private String private String private String secondNamesecondNamesecondNamesecondName; // Store for second name; // Store for second name; // Store for second name; // Store for second name
private long private long private long private long aWhileaWhileaWhileaWhile; // Delay in milliseconds; // Delay in milliseconds; // Delay in milliseconds; // Delay in milliseconds
public TryThread1(String public TryThread1(String public TryThread1(String public TryThread1(String firstNamefirstNamefirstNamefirstName, String , String , String , String secondNamesecondNamesecondNamesecondName, long delay), long delay), long delay), long delay)
{{{{
this.firstNamethis.firstNamethis.firstNamethis.firstName = = = = firstNamefirstNamefirstNamefirstName; // Store the first name; // Store the first name; // Store the first name; // Store the first name
this.secondNamethis.secondNamethis.secondNamethis.secondName = = = = secondNamesecondNamesecondNamesecondName; // Store the second name; // Store the second name; // Store the second name; // Store the second name
aWhileaWhileaWhileaWhile = delay; // Store the delay= delay; // Store the delay= delay; // Store the delay= delay; // Store the delay
////////setDaemon(truesetDaemon(truesetDaemon(truesetDaemon(true); // Thread is daemon); // Thread is daemon); // Thread is daemon); // Thread is daemon
}}}}
public static void public static void public static void public static void main(Stringmain(Stringmain(Stringmain(String[] [] [] [] argsargsargsargs))))
{{{{
// Create three threads// Create three threads// Create three threads// Create three threads
Thread first = new Thread first = new Thread first = new Thread first = new TryThread("HopalongTryThread("HopalongTryThread("HopalongTryThread("Hopalong ", "Cassidy ", 200L);", "Cassidy ", 200L);", "Cassidy ", 200L);", "Cassidy ", 200L);
Thread second = new Thread second = new Thread second = new Thread second = new TryThread("MarilynTryThread("MarilynTryThread("MarilynTryThread("Marilyn ", "Monroe ", 300L);", "Monroe ", 300L);", "Monroe ", 300L);", "Monroe ", 300L);
Thread third = new Thread third = new Thread third = new Thread third = new TryThread("SlimTryThread("SlimTryThread("SlimTryThread("Slim ", "Pickens ", 500L);", "Pickens ", 500L);", "Pickens ", 500L);", "Pickens ", 500L);
System.out.println("PressSystem.out.println("PressSystem.out.println("PressSystem.out.println("Press Enter when you have had enough...Enter when you have had enough...Enter when you have had enough...Enter when you have had enough...\\\\n");n");n");n");
first.startfirst.startfirst.startfirst.start(); // Start the first thread(); // Start the first thread(); // Start the first thread(); // Start the first thread
second.startsecond.startsecond.startsecond.start(); // Start the second thread(); // Start the second thread(); // Start the second thread(); // Start the second thread
third.startthird.startthird.startthird.start(); // Start the third thread(); // Start the third thread(); // Start the third thread(); // Start the third thread
Osnova18
trytrytrytry
{{{{
System.in.System.in.System.in.System.in.readreadreadread();();();(); // Wait // Wait // Wait // Wait untiluntiluntiluntil EnterEnterEnterEnter keykeykeykey pressedpressedpressedpressed
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln("("("("EnterEnterEnterEnter pressedpressedpressedpressed............\\\\n");n");n");n");
// // // // InterruptInterruptInterruptInterrupt thethethethe threadsthreadsthreadsthreads
firstfirstfirstfirst....interruptinterruptinterruptinterrupt();();();();
secondsecondsecondsecond....interruptinterruptinterruptinterrupt();();();();
thirdthirdthirdthird....interruptinterruptinterruptinterrupt();();();();
} } } }
catchcatchcatchcatch ((((IOExceptionIOExceptionIOExceptionIOException e) // Handle IO e) // Handle IO e) // Handle IO e) // Handle IO exceptionexceptionexceptionexception
{{{{
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln(e); // (e); // (e); // (e); // OutputOutputOutputOutput thethethethe exceptionexceptionexceptionexception
}}}}
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln("("("("EndingEndingEndingEnding mainmainmainmain()");()");()");()");
returnreturnreturnreturn;;;;
}}}}
// // // // MethodMethodMethodMethod wherewherewherewhere threadthreadthreadthread executionexecutionexecutionexecution willwillwillwill startstartstartstart
Osnova19
public public public public voidvoidvoidvoid run() {run() {run() {run() {
trytrytrytry {{{{
whilewhilewhilewhile((((truetruetruetrue ) // ) // ) // ) // LoopLoopLoopLoop indefinitelyindefinitelyindefinitelyindefinitely............
{{{{
SystemSystemSystemSystem....outoutoutout....printprintprintprint((((firstNamefirstNamefirstNamefirstName); // ); // ); // ); // OutputOutputOutputOutput firstfirstfirstfirst namenamenamename
sleepsleepsleepsleep((((aWhileaWhileaWhileaWhile); // Wait ); // Wait ); // Wait ); // Wait aWhileaWhileaWhileaWhile msecmsecmsecmsec....
SystemSystemSystemSystem....outoutoutout....printprintprintprint((((secondNamesecondNamesecondNamesecondName + "+ "+ "+ "\\\\n"); // n"); // n"); // n"); // OutputOutputOutputOutput secondsecondsecondsecond namenamenamename
}}}}
}}}}
catchcatchcatchcatch((((InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e) // Handle e) // Handle e) // Handle e) // Handle threadthreadthreadthread interruptioninterruptioninterruptioninterruption
{{{{
// // // // OutputOutputOutputOutput thethethethe exceptionexceptionexceptionexception
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln((((firstNamefirstNamefirstNamefirstName + + + + secondNamesecondNamesecondNamesecondName + e); }+ e); }+ e); }+ e); }
}}}}
}}}}
HopalongHopalongHopalongHopalong Pickens Pickens Pickens Pickens
Slim Monroe Slim Monroe Slim Monroe Slim Monroe
Marilyn Cassidy Marilyn Cassidy Marilyn Cassidy Marilyn Cassidy
HopalongHopalongHopalongHopalong
Cassidy Cassidy Cassidy Cassidy
HopalongHopalongHopalongHopalong Enter pressed...Enter pressed...Enter pressed...Enter pressed...
HopalongHopalongHopalongHopalong Cassidy Cassidy Cassidy Cassidy java.lang.InterruptedExceptionjava.lang.InterruptedExceptionjava.lang.InterruptedExceptionjava.lang.InterruptedException: sleep interrupted: sleep interrupted: sleep interrupted: sleep interrupted
Ending main()Ending main()Ending main()Ending main()
Slim Pickens Slim Pickens Slim Pickens Slim Pickens java.lang.InterruptedExceptionjava.lang.InterruptedExceptionjava.lang.InterruptedExceptionjava.lang.InterruptedException: sleep interrupted: sleep interrupted: sleep interrupted: sleep interrupted
Marilyn Monroe Marilyn Monroe Marilyn Monroe Marilyn Monroe java.lang.InterruptedExceptionjava.lang.InterruptedExceptionjava.lang.InterruptedExceptionjava.lang.InterruptedException: sleep interrupted: sleep interrupted: sleep interrupted: sleep interrupted
20
3 Implementace vlákna
1. Vytvoření podtřídy od třídy Thread a předeklarováním (zastíněním) metody runnew Thread(this).start();
• vlákna jsou vytvořena a odstartovaná uvnitř třídy
2. Implementací rozhraníRunnablenew MyThread().start();
• vytvoří a odstartuje vlákno třídy MyThread, které provede zastíněnou (předeklarovanou) metodu run třídy MyThread
21
Ukon čení programu vícevláknové aplikace
• V metodě run se deklarují tzv. životní pravidla daného vlákna. Pokud se vlákno dostane na konec metody run je jeho „život“ ukončen
• Příklad nekonečné smyčky – vlákno main je ukončeno, některá další vlákna pokračují
Osnova22
classclassclassclass RunForeverRunForeverRunForeverRunForever implementsimplementsimplementsimplements RunnableRunnableRunnableRunnable {{{{
public static public static public static public static voidvoidvoidvoid mainmainmainmain( ( ( ( StringStringStringString[ ] [ ] [ ] [ ] argsargsargsargs ) {) {) {) {
RunForeverRunForeverRunForeverRunForever memememe = = = = newnewnewnew RunForeverRunForeverRunForeverRunForever(); (); (); (); // instance// instance// instance// instance
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( "( "( "( "mainmainmainmain threadthreadthreadthread aboutaboutaboutabout to exit!" );to exit!" );to exit!" );to exit!" );
newnewnewnew ThreadThreadThreadThread( ( ( ( memememe ).start();).start();).start();).start();
} //*** } //*** } //*** } //*** mainmainmainmain exitsexitsexitsexits sosososo mainmainmainmain ThreadThreadThreadThread stopsstopsstopsstops
public public public public voidvoidvoidvoid run() {run() {run() {run() {
whilewhilewhilewhile ( ( ( ( truetruetruetrue ) {) {) {) {
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( "2nd ( "2nd ( "2nd ( "2nd ThreadThreadThreadThread sayssayssayssays ''''hihihihi!'..." );!'..." );!'..." );!'..." );
trytrytrytry {{{{
ThreadThreadThreadThread....sleepsleepsleepsleep( 10 ); // pause 10 ( 10 ); // pause 10 ( 10 ); // pause 10 ( 10 ); // pause 10 millisecondsmillisecondsmillisecondsmilliseconds
} } } } catchcatchcatchcatch( ( ( ( InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e ) { e ) { e ) { e ) { SystemSystemSystemSystem....errerrerrerr....printlnprintlnprintlnprintln( e ); }( e ); }( e ); }( e ); }
}}}}
}}}}
}}}}
Osnova23
main thread about to exit!main thread about to exit!main thread about to exit!main thread about to exit!
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
244 Vlákna uživatele a démoniUser and Daemon Threads
• Vlákna mohou být dvou typů:– vlákna uživatele (doposud)
– démoni – pokud skončí vlákno main, skončí takémetody:setDeamon(boolean);isDaemon();
Osnova25
classclassclassclass NotRunForeverNotRunForeverNotRunForeverNotRunForever implementsimplementsimplementsimplements RunnableRunnableRunnableRunnable {{{{
//*** //*** //*** //*** vlaknovlaknovlaknovlakno mainmainmainmain je je je je uzivatelskeuzivatelskeuzivatelskeuzivatelske ne ne ne ne vlaknovlaknovlaknovlakno demonudemonudemonudemonu
public static public static public static public static voidvoidvoidvoid mainmainmainmain( ( ( ( StringStringStringString[ ] [ ] [ ] [ ] argsargsargsargs ) { ) { ) { ) {
NotRunForeverNotRunForeverNotRunForeverNotRunForever memememe = = = = newnewnewnew NotRunForeverNotRunForeverNotRunForeverNotRunForever();();();();
ThreadThreadThreadThread t1 = t1 = t1 = t1 = newnewnewnew ThreadThreadThreadThread( ( ( ( memememe ););););
t1.t1.t1.t1.setDaemonsetDaemonsetDaemonsetDaemon( ( ( ( truetruetruetrue ); ); ); ); //*** t1 je //*** t1 je //*** t1 je //*** t1 je demondemondemondemon, ne , ne , ne , ne uzivatelskeuzivatelskeuzivatelskeuzivatelske vlaknovlaknovlaknovlakno
t1.start();t1.start();t1.start();t1.start();
trytrytrytry { { { {
ThreadThreadThreadThread....sleepsleepsleepsleep( 50 ); //*** ( 50 ); //*** ( 50 ); //*** ( 50 ); //*** vlaknovlaknovlaknovlakno mainmainmainmain
} } } } catchcatchcatchcatch( ( ( ( InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e ) { e ) { e ) { e ) { SystemSystemSystemSystem....errerrerrerr....printlnprintlnprintlnprintln( e ); }( e ); }( e ); }( e ); }
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( "( "( "( "mainmainmainmain threadthreadthreadthread aboutaboutaboutabout to exit!" );to exit!" );to exit!" );to exit!" );
} } } } //*** //*** //*** //*** mainmainmainmain konci, t1 zastavuje, aplikace koncikonci, t1 zastavuje, aplikace koncikonci, t1 zastavuje, aplikace koncikonci, t1 zastavuje, aplikace konci
public public public public voidvoidvoidvoid run() {run() {run() {run() {
whilewhilewhilewhile ( ( ( ( truetruetruetrue ) {) {) {) {
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( "2nd ( "2nd ( "2nd ( "2nd ThreadThreadThreadThread sayssayssayssays ''''hihihihi!'..." );!'..." );!'..." );!'..." );
trytrytrytry {{{{
ThreadThreadThreadThread....sleepsleepsleepsleep( 10 ); // pauza 10 milisekund( 10 ); // pauza 10 milisekund( 10 ); // pauza 10 milisekund( 10 ); // pauza 10 milisekund
} } } } catchcatchcatchcatch( ( ( ( InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e ) { e ) { e ) { e ) { SystemSystemSystemSystem....errerrerrerr....printlnprintlnprintlnprintln( e ); }( e ); }( e ); }( e ); }
}}}}
}}}}
}}}}
Osnova26
Výpis aplikace
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
main thread about to exit!main thread about to exit!main thread about to exit!main thread about to exit!
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...2nd Thread says 'hi!'...
275 Priority vláken a plánování vlákenThread Priorities and Thread Scheduling
• Java thread priority– Priority v rozsahu 1-10
• Timeslicing dávkováníčasu– Každé vlákno dostane přidělený čas procesoru (nazvaný
kvantum)
– Nechává běžet vlákna s nejvyšší prioritou
– Pravidelná alternace mezi vlákny dané priority
• víceúrovňová fronta s prioritami pro plánováníběhu vláken (další obrázek)
28
Priorita vláken – p říklad plánování
Priority 9
Priority 8
Priority 7
Priority 10
Priority 6
Priority 5
Priority 4
Priority 3
Priority 2
Priority 1
A B
D
C
E F
G
H I
J K
Ready threads
Thread.MIN_PRIORITY
Thread.MAX_PRIORITY
Thread.NORM_PRIORITY
Osnova29
classclassclassclass ThreadPriorityThreadPriorityThreadPriorityThreadPriority implementsimplementsimplementsimplements RunnableRunnableRunnableRunnable {{{{
public static public static public static public static voidvoidvoidvoid mainmainmainmain( ( ( ( StringStringStringString[ ] [ ] [ ] [ ] argsargsargsargs ) {) {) {) {
ThreadPriorityThreadPriorityThreadPriorityThreadPriority tptptptp = = = = newnewnewnew ThreadPriorityThreadPriorityThreadPriorityThreadPriority();();();();
tptptptp....testPrioritytestPrioritytestPrioritytestPriority();();();();
}}}}
public public public public voidvoidvoidvoid run() {run() {run() {run() {
whilewhilewhilewhile ( ( ( ( truetruetruetrue ) ) ) )
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( ( ( ( ThreadThreadThreadThread....currentThreadcurrentThreadcurrentThreadcurrentThread().().().().getNamegetNamegetNamegetName() );() );() );() );
}}}}
private private private private voidvoidvoidvoid testPrioritytestPrioritytestPrioritytestPriority() {() {() {() {
ThreadThreadThreadThread t1 = t1 = t1 = t1 = newnewnewnew ThreadThreadThreadThread( ( ( ( thisthisthisthis, ", ", ", "NormalniNormalniNormalniNormalni priorita" );priorita" );priorita" );priorita" );
t1.start(); //*** t1.start(); //*** t1.start(); //*** t1.start(); //*** startsstartsstartsstarts firstfirstfirstfirst
ThreadThreadThreadThread t2 = t2 = t2 = t2 = newnewnewnew ThreadThreadThreadThread( ( ( ( thisthisthisthis, "Max priorita" );, "Max priorita" );, "Max priorita" );, "Max priorita" );
t2.t2.t2.t2.setPrioritysetPrioritysetPrioritysetPriority( ( ( ( ThreadThreadThreadThread.MAX_PRIORITY );.MAX_PRIORITY );.MAX_PRIORITY );.MAX_PRIORITY );
t2.start();t2.start();t2.start();t2.start();
}}}}
}}}}
Osnova30
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
NormalniNormalniNormalniNormalni prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
Max Max Max Max prioritaprioritaprioritapriorita
316 Stavy vláken: Životní cyklus vlákna (životní pravidla)
• Stavy vláken– Born state – stav vytvoření
• Vlákno bylo právě vytvořeno
– Ready state• Vlákno vyvolalo metodu start
• Vlákno nyní může být vykonáváno (execute)
– Running state• Vláknu je přidělen procesor a běží (is running)
– Dead state• Vlákno dokončilo nebo ukončilo svoji činnost
• Vlákno ukončeno systémem
32
Životní cyklus vlákna – stavový diagram
Ready
Running
BlockedSleepingWaiting
start
issue I/O
requestwait
notify
notifyAll
timeo
ut e
xpire
sinterrupt
thread dispatch(assign a processor)
quantum expirationyield
sleep
complete
sleep interval expires
interrupt
Born
enter synchronized
statement
I/O com
pletesacquire lockinterrupt
Když se vlákno ukončí (návrat z metody run), dosáhne stavu ukončení - Dead(konečný stav)
33
Jak učinit vlákno „neb ěžícím“
• Vyvolat metodu sleep()
• Vlákno vyvolá metodu wait() – a čeká na splnění specifické podmínky a uvolňuje objekty, které jsou s aktuálním vláknem uzamknuty
• Vlákno je blokováno vstupně/výstupními operacemi
• Vyvolat metody yield() (vzdává se činnosti)
34
Zastavení – stopnutí vlákna
• Přirozeně, když se dostane v metodě run na konec svých životních pravidel
• příkazem System.exit(0);
• thread.interrupt();
35
Metoda join()
• Čekání, až jiné vlákno zanikne; na jiné vlákno se použije metoda join().
• Metoda join() zadrží aktuální vlákno tak dlouho, dokud určené vlákno nezanikne.
• Dá se proto částečně použít k synchronizaci vláken.
• Následující program – dvě vlákna plus a minus(přičítá, odečítá 1) se střídají pomocí metody join() – výsledný součet pro malé N nulový pro velké N různé výsledky
Osnova36
classclassclassclass SyncEx1 {SyncEx1 {SyncEx1 {SyncEx1 {
public static public static public static public static voidvoidvoidvoid mainmainmainmain( ( ( ( StringStringStringString[ ] [ ] [ ] [ ] argsargsargsargs ) {) {) {) {
ifififif ( ( ( ( argsargsargsargs....lengthlengthlengthlength < 1 ) {< 1 ) {< 1 ) {< 1 ) {
SystemSystemSystemSystem....errerrerrerr....printlnprintlnprintlnprintln( "( "( "( "javajavajavajava SyncEx1 <SyncEx1 <SyncEx1 <SyncEx1 <loopsloopsloopsloops per per per per threadthreadthreadthread>" );>" );>" );>" );
SystemSystemSystemSystem.exit( .exit( .exit( .exit( ----1 );1 );1 );1 );
}}}}
intintintint n = n = n = n = IntegerIntegerIntegerInteger....parseIntparseIntparseIntparseInt( ( ( ( argsargsargsargs[ 0 ] ); // iteraci na [ 0 ] ); // iteraci na [ 0 ] ); // iteraci na [ 0 ] ); // iteraci na vlaknovlaknovlaknovlakno
MyThreadEMyThreadEMyThreadEMyThreadE plus = plus = plus = plus = newnewnewnew MyThreadEMyThreadEMyThreadEMyThreadE( +1, n ), // plus ( +1, n ), // plus ( +1, n ), // plus ( +1, n ), // plus zvysizvysizvysizvysi
minus = minus = minus = minus = newnewnewnew MyThreadEMyThreadEMyThreadEMyThreadE( ( ( ( ----1, n ); // minus 1, n ); // minus 1, n ); // minus 1, n ); // minus snizisnizisnizisnizi
plus.start(); minus.start();plus.start(); minus.start();plus.start(); minus.start();plus.start(); minus.start();
// // // // cekacekacekaceka azazazaz obeobeobeobe vlaknavlaknavlaknavlakna dokoncidokoncidokoncidokonci, , , , predpredpredpred tiskem tiskem tiskem tiskem vysledkuvysledkuvysledkuvysledku
trytrytrytry {{{{
plus.plus.plus.plus.joinjoinjoinjoin(); minus.(); minus.(); minus.(); minus.joinjoinjoinjoin(); (); (); (); ////////mainmainmainmain cekacekacekaceka na na na na ukonceniukonceniukonceniukonceni plus a minusplus a minusplus a minusplus a minus
} } } } catchcatchcatchcatch( ( ( ( InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e ) { }e ) { }e ) { }e ) { }
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( n + " ( n + " ( n + " ( n + " iterationsiterationsiterationsiterations eacheacheacheach: " + : " + : " + : " + MyThreadEMyThreadEMyThreadEMyThreadE....sharedsharedsharedshared ););););
}}}}
}}}}
classclassclassclass MyThreadEMyThreadEMyThreadEMyThreadE extendsextendsextendsextends ThreadThreadThreadThread {{{{
static static static static intintintint shared; shared; shared; shared; //*** //*** //*** //*** sdilenesdilenesdilenesdilene vsemivsemivsemivsemi objekty objekty objekty objekty MyThreadEMyThreadEMyThreadEMyThreadE
private private private private intintintint n;n;n;n;
private private private private intintintint t;t;t;t;
MyThreadEMyThreadEMyThreadEMyThreadE( ( ( ( intintintint type, type, type, type, intintintint howManyhowManyhowManyhowMany ) { t = type; n = ) { t = type; n = ) { t = type; n = ) { t = type; n = howManyhowManyhowManyhowMany; }; }; }; }
public public public public voidvoidvoidvoid run() {run() {run() {run() {
forforforfor ( ( ( ( intintintint i = 0; i < n; i++ )i = 0; i < n; i++ )i = 0; i < n; i++ )i = 0; i < n; i++ )
ifififif ( t > 0 )( t > 0 )( t > 0 )( t > 0 )
shared = shared + 1;shared = shared + 1;shared = shared + 1;shared = shared + 1;
elseelseelseelse
shared = shared shared = shared shared = shared shared = shared ---- 1;1;1;1;
}}}}
}}}}
37Kritická sekce – vzájemné vylou čeníMutual Exclusion
• Kritická sekce –část kódu, ke které musí mít vlákno výlučný (exklusivní) přístup.
• Operace: shared = shared + 1;se skládá ze součtu a přiřazení (2 atomickéoperace)
• Může být rozdělena na dvě části – dostaneme chybné výsledky
38
Synchronizace
• Nutná synchronizace
• Cíl synchronizace – v případě, že několik vláken vyžaduje přístup k jedinému zdroji, mohl tento přístup v jediném okamžiku dostat jen jedno vlákno.
• Možnosti synchronizace:– na úrovni metod – synchronizovat celé metody
– na úrovni bloků – pomocí synchronizace bloků.
• Klíčové slovo synchronized způsobí, že metody, bloky se budou chovat jako atomické -nedělitelné
39
Synchronizované metody
class MojeTrida {
public synchronized void metoda1() {
// kód metody . . .
}
public synchronized void metoda2() {
// kód metody
}
public void metoda3() {
//kód metody
}
Osnova40
Zabezpečí pouze výlučný přístup –exkluzivní přístup
classclassclassclass MyThreadSMyThreadSMyThreadSMyThreadS extendsextendsextendsextends ThreadThreadThreadThread {{{{
static static static static intintintint shared; //*** shared; //*** shared; //*** shared; //*** sdilenesdilenesdilenesdilene vsemivsemivsemivsemi objekty objekty objekty objekty MyThreadSMyThreadSMyThreadSMyThreadS
private private private private intintintint n;n;n;n;
private private private private intintintint t;t;t;t;
private synchronized private synchronized private synchronized private synchronized voidvoidvoidvoid plusOrMinusplusOrMinusplusOrMinusplusOrMinus(){(){(){(){
ifififif(t>0)(t>0)(t>0)(t>0)
shared = shared + 1;shared = shared + 1;shared = shared + 1;shared = shared + 1;
elseelseelseelse
shared = shared shared = shared shared = shared shared = shared ---- 1;1;1;1;
}}}}
MyThreadSMyThreadSMyThreadSMyThreadS( ( ( ( intintintint type, type, type, type, intintintint howManyhowManyhowManyhowMany ) { t = type; n = ) { t = type; n = ) { t = type; n = ) { t = type; n = howManyhowManyhowManyhowMany; }; }; }; }
public public public public voidvoidvoidvoid run() {run() {run() {run() {
plusOrMinusplusOrMinusplusOrMinusplusOrMinus();();();();
////////forforforfor ( ( ( ( intintintint i = 0; i < n; i++ )i = 0; i < n; i++ )i = 0; i < n; i++ )i = 0; i < n; i++ )
// // // // ifififif ( t > 0 )( t > 0 )( t > 0 )( t > 0 )
// shared = shared + 1;// shared = shared + 1;// shared = shared + 1;// shared = shared + 1;
// // // // elseelseelseelse
// shared = shared // shared = shared // shared = shared // shared = shared ---- 1;1;1;1;
}}}}
}}}}
41
Synchronizované bloky
• Pružnější mechanismus než synchronizovanémetody, protože se váže pouze na blok a daný objekt, který je buď uzamknutý, nebo odemčený.
• Každá instance třídy java.lang.Object, nebo libovolný potomek si udržuje zámek (někdy zvaný monitor )– jedná se u určitou formu detekce stavu s cílem poskytnout
výhradní přístup k danému prostředku
– klíčové slovo synchronized je vždy implicitně nebo explicitně přidruženo k instanci typu Object
42
Synchronizované bloky
• Předtím, než je vláknu dovoleno vstoupit do synchronizovaného bloku musí získat zámek objektu přidruženého k danému kódu.
• Pokud jedno vlákno zámek získá, jiné jej nezíská a jeho běh bude blokovaný do doby, než bude zámek uvolněn.
• Kromě zámku si ještě každý objekt udržuje seznam blokovaných vláken – pokud vlákno nemůže získat zámek objektu, je automaticky uloženo do seznamu (fronty) a pak z něho vybráno.
Osnova43
classclassclassclass BankBankBankBank
{{{{
// // // // PerformPerformPerformPerform a a a a transactiontransactiontransactiontransaction
public public public public voidvoidvoidvoid doTransactiondoTransactiondoTransactiondoTransaction((((TransactionTransactionTransactionTransaction transactiontransactiontransactiontransaction))))
{{{{
intintintint balance = balance = balance = balance = transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount().().().().getBalancegetBalancegetBalancegetBalance(); (); (); ();
switchswitchswitchswitch((((transactiontransactiontransactiontransaction....getTransactionTypegetTransactionTypegetTransactionTypegetTransactionType())())())())
{{{{
casecasecasecase TransactionTransactionTransactionTransaction.CREDIT:.CREDIT:.CREDIT:.CREDIT:
synchronized(synchronized(synchronized(synchronized(transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount())())())())
{{{{
// // // // GetGetGetGet currentcurrentcurrentcurrent balancebalancebalancebalance
intintintint balance = balance = balance = balance = transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount().().().().getBalancegetBalancegetBalancegetBalance(); (); (); ();
// // // // CreditsCreditsCreditsCredits requirerequirerequirerequire a lot a lot a lot a lot ofofofof checkscheckscheckschecks............
trytrytrytry
{{{{
ThreadThreadThreadThread....sleepsleepsleepsleep(100);(100);(100);(100);
}}}}
catchcatchcatchcatch((((InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e)e)e)e)
{{{{
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln(e);(e);(e);(e);
}}}}
balance += balance += balance += balance += transactiontransactiontransactiontransaction....getAmountgetAmountgetAmountgetAmount(); // (); // (); // (); // IncrementIncrementIncrementIncrement thethethethe balancebalancebalancebalance
// // // // RestoreRestoreRestoreRestore accountaccountaccountaccount balancebalancebalancebalance
transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount().().().().setBalancesetBalancesetBalancesetBalance(balance); (balance); (balance); (balance); breakbreakbreakbreak;;;;
}}}}
Osnova44
casecasecasecase TransactionTransactionTransactionTransaction.DEBIT:.DEBIT:.DEBIT:.DEBIT:
synchronized(synchronized(synchronized(synchronized(transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount())())())())
{{{{
// // // // GetGetGetGet currentcurrentcurrentcurrent balancebalancebalancebalance
intintintint balance = balance = balance = balance = transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount().().().().getBalancegetBalancegetBalancegetBalance(); (); (); ();
// // // // DebitsDebitsDebitsDebits requirerequirerequirerequire eveneveneveneven more more more more checkscheckscheckschecks............
trytrytrytry
{{{{
ThreadThreadThreadThread....sleepsleepsleepsleep(150);(150);(150);(150);
}}}}
catchcatchcatchcatch((((InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e)e)e)e)
{{{{
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln(e);(e);(e);(e);
}}}}
balance balance balance balance ----= = = = transactiontransactiontransactiontransaction....getAmountgetAmountgetAmountgetAmount(); // (); // (); // (); // DecrementDecrementDecrementDecrement thethethethe balancebalancebalancebalance
// // // // RestoreRestoreRestoreRestore accountaccountaccountaccount balancebalancebalancebalance
transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount().().().().setBalancesetBalancesetBalancesetBalance(balance); (balance); (balance); (balance); breakbreakbreakbreak;;;;
}}}}
default: // default: // default: // default: // WeWeWeWe shouldshouldshouldshould nevernevernevernever getgetgetget herehereherehere
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln("Invalid ("Invalid ("Invalid ("Invalid transactiontransactiontransactiontransaction");");");");
SystemSystemSystemSystem.exit(1);.exit(1);.exit(1);.exit(1);
}}}}
// // // // RestoreRestoreRestoreRestore thethethethe accountaccountaccountaccount balancebalancebalancebalance
transactiontransactiontransactiontransaction....getAccountgetAccountgetAccountgetAccount().().().().setBalancesetBalancesetBalancesetBalance(balance); }(balance); }(balance); }(balance); }
}}}}
45
Komunikace mezi vlákny
• Probrali jsme uzamčení metod nebo bloků kódu pomocí synchronizace
• Používáme příkaz while k testování stavu vlákna v časových intervalech daných voláním metody sleep() – není nejlepšířešení
• Třída Object definuje metody wait(), notify() a notifyAll() – účinnější řešení situace
1. Tyto metody dědí všechny podtřídy třídy Object
2. Mohou být volány jen zevnitřsynchronizovaných metod nebo zevnitř
synchronizovaného bloku kódu.
46
Komunikace mezi vlákny
• Při vyvolání odjinud bude vyvolána výjimka IllegalMonitorStateException
• Základní myšlenkou metod wait() a notify() je poskytnout metodám nebo blokům kódu, kteréjsou synchronizovány konkrétním objektem, prostředek ke komunikaci.
• jedem blok může volat wait() k pozastavení svých operací, dokud nějaká jiná metoda nebo blok kódu synchronizovaný stejným objektem jej nějakým způsobem nezmění a nezavolánotify(), čímžnaznačí dokončení změny.
47
Touto metodou se znovu spustí všechna vlákna, která volala metodu wait() objektu, ke kterému patří metoda notifyAll().
notifyAll()
Metodou se znova spustí vlákno, které vyvolalo metodu wait() objektu, ke kterému patří metoda notify(). Pokud pro tento objekt volalo wait() více objektů, není žádná kontrola nad tím, kterému z těchto vláken bude notify() určeno – lépe použít notifyAll().
notify()
Tato verze pozastaví aktuální vlákno dokud neuplyne stanovený počet milisekund, nebo není dříve zaslaná zpráva notify() nebo notifyAll() objektu, ke kterému patří metoda wait()..
wait(longcasLim)
Metoda pozastaví aktuální vlákno až do doby volání metody notify() nebo notifyAll() pro objekt, ke kterému patří metoda wait(). Při zavolání této metody vlákno uvolní synchronizačnízámek, který má na objektu, takže se může provádět jakákoli jiná metoda nebo blok kódu, které jsou synchronizovány stejným objektem.
wait()
PopisMetoda
48
Příklad komunikace vláken
• Metoda main vytvoří N (8) vláken třídy MyThreadW
• Třída MyThreadW má statické pole znakůsdílených objektů
• Každé vlákno má id a char (identifikátor a znak) začínající od 0 ‘A’
• Start se provádí v obráceném pořadí od 7 ‘H’
• Výpis je opět uspořádán od A … H
Osnova49
classclassclassclass SyncWaitExSyncWaitExSyncWaitExSyncWaitEx {{{{
public static public static public static public static voidvoidvoidvoid mainmainmainmain( ( ( ( StringStringStringString[ ] [ ] [ ] [ ] argsargsargsargs ) {) {) {) {
finalfinalfinalfinal intintintint n = 8;n = 8;n = 8;n = 8;
MyThreadWMyThreadWMyThreadWMyThreadW[ ] [ ] [ ] [ ] mtmtmtmt = = = = newnewnewnew MyThreadWMyThreadWMyThreadWMyThreadW[ n ];[ n ];[ n ];[ n ];
charcharcharchar c = 'A';c = 'A';c = 'A';c = 'A';
//*** //*** //*** //*** vytvarivytvarivytvarivytvari a inicializuje a inicializuje a inicializuje a inicializuje vlaknavlaknavlaknavlakna
forforforfor ( ( ( ( intintintint i = 0; i < n; i++ ) i = 0; i < n; i++ ) i = 0; i < n; i++ ) i = 0; i < n; i++ )
mtmtmtmt[ i ] = [ i ] = [ i ] = [ i ] = newnewnewnew MyThreadWMyThreadWMyThreadWMyThreadW( i, c++ );( i, c++ );( i, c++ );( i, c++ );
//*** startuje //*** startuje //*** startuje //*** startuje vlaknavlaknavlaknavlakna v v v v obracenemobracenemobracenemobracenem poradiporadiporadiporadi
forforforfor ( ( ( ( intintintint i = n i = n i = n i = n ---- 1; i >= 0; i1; i >= 0; i1; i >= 0; i1; i >= 0; i-------- ))))
mtmtmtmt[ i ].start();[ i ].start();[ i ].start();[ i ].start();
}}}}
}}}}
classclassclassclass MyThreadWMyThreadWMyThreadWMyThreadW extendsextendsextendsextends ThreadThreadThreadThread {{{{
private private private private intintintint id; //*** id; //*** id; //*** id; //*** identifikatoridentifikatoridentifikatoridentifikator
private private private private charcharcharchar c; //*** znak, c; //*** znak, c; //*** znak, c; //*** znak, kterykterykteryktery se se se se zapisezapisezapisezapise do do do do sdilenehosdilenehosdilenehosdileneho pole pole pole pole
private static private static private static private static intintintint turnturnturnturn = 0;= 0;= 0;= 0;
private static private static private static private static finalfinalfinalfinal intintintint n = 8; n = 8; n = 8; n = 8;
private static private static private static private static charcharcharchar queuequeuequeuequeue[ ] = [ ] = [ ] = [ ] = newnewnewnew charcharcharchar[ n ]; //** [ n ]; //** [ n ]; //** [ n ]; //** sdilenesdilenesdilenesdilene polepolepolepole
public public public public MyThreadWMyThreadWMyThreadWMyThreadW( ( ( ( intintintint i, i, i, i, charcharcharchar chchchch ) { id = i; c = ) { id = i; c = ) { id = i; c = ) { id = i; c = chchchch; }; }; }; }
public public public public voidvoidvoidvoid run() {run() {run() {run() {
whilewhilewhilewhile ( ( ( ( truetruetruetrue ) ) ) )
writeCharwriteCharwriteCharwriteChar();();();();
}}}}
Osnova50
//*** synchronizace //*** synchronizace //*** synchronizace //*** synchronizace zabezpecujicizabezpecujicizabezpecujicizabezpecujici pouze jedno pouze jedno pouze jedno pouze jedno vlaknovlaknovlaknovlakno v v v v danemdanemdanemdanem casecasecasecase
// zapisuje do fronty apod. // zapisuje do fronty apod. // zapisuje do fronty apod. // zapisuje do fronty apod. VlaknaVlaknaVlaknaVlakna cekajicekajicekajicekaji, kdy , kdy , kdy , kdy prijdouprijdouprijdouprijdou na radu.na radu.na radu.na radu.
private synchronized private synchronized private synchronized private synchronized voidvoidvoidvoid writeCharwriteCharwriteCharwriteChar() {() {() {() {
//*** //*** //*** //*** uvolneniuvolneniuvolneniuvolneni locklocklocklock a a a a cekacekacekaceka azazazaz prijdeprijdeprijdeprijde na raduna raduna raduna radu
whilewhilewhilewhile ( ( ( ( turnturnturnturn != id ) != id ) != id ) != id )
trytrytrytry {{{{
wait( 20 ); // 20 milisekundwait( 20 ); // 20 milisekundwait( 20 ); // 20 milisekundwait( 20 ); // 20 milisekund
} } } } catchcatchcatchcatch( ( ( ( InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e ) { }e ) { }e ) { }e ) { }
queuequeuequeuequeue[ [ [ [ turnturnturnturn++ ] = ++ ] = ++ ] = ++ ] = thisthisthisthis.c;.c;.c;.c;
ifififif ( ( ( ( turnturnturnturn == n ) { //*** je fronta plna?== n ) { //*** je fronta plna?== n ) { //*** je fronta plna?== n ) { //*** je fronta plna?
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( ( ( ( queuequeuequeuequeue ); //** pokud ano, vytiskni ji); //** pokud ano, vytiskni ji); //** pokud ano, vytiskni ji); //** pokud ano, vytiskni ji
turnturnturnturn = 0; // a nastav = 0; // a nastav = 0; // a nastav = 0; // a nastav poradiporadiporadiporadi }}}}turnturnturnturn] na nulu] na nulu] na nulu] na nulu
}}}}
notifyAll(); //*** vzbudit notifyAll(); //*** vzbudit notifyAll(); //*** vzbudit notifyAll(); //*** vzbudit cekajicicekajicicekajicicekajici vlaknavlaknavlaknavlakna
}}}}
}}}}
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
ABCDEFGHABCDEFGHABCDEFGHABCDEFGH
51
Producent / konzument
• Producent – vyrábí, konzument – konzumuje
• CubbyHole – vyrovnávací a synchronizační buffer
• Testovací třída
Osnova52
public public public public classclassclassclass ProducerProducerProducerProducer extendsextendsextendsextends ThreadThreadThreadThread {{{{
private private private private CubbyHoleCubbyHoleCubbyHoleCubbyHole cubbyholecubbyholecubbyholecubbyhole;;;;
private private private private intintintint numbernumbernumbernumber;;;;
public public public public ProducerProducerProducerProducer((((CubbyHoleCubbyHoleCubbyHoleCubbyHole c, c, c, c, intintintint numbernumbernumbernumber) {) {) {) {
cubbyholecubbyholecubbyholecubbyhole = c;= c;= c;= c;
thisthisthisthis....numbernumbernumbernumber = = = = numbernumbernumbernumber;;;;
}}}}
public public public public voidvoidvoidvoid run() {run() {run() {run() {
forforforfor ((((intintintint i = 0; i < 10; i++) {i = 0; i < 10; i++) {i = 0; i < 10; i++) {i = 0; i < 10; i++) {
cubbyholecubbyholecubbyholecubbyhole.put(.put(.put(.put(numbernumbernumbernumber, i);, i);, i);, i);
trytrytrytry {{{{
sleepsleepsleepsleep((((((((intintintint)()()()(MathMathMathMath....randomrandomrandomrandom() * 100));() * 100));() * 100));() * 100));
} } } } catchcatchcatchcatch ((((InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e) { }e) { }e) { }e) { }
}}}}
}}}}
}}}}
Osnova53
public public public public classclassclassclass ConsumerConsumerConsumerConsumer extendsextendsextendsextends ThreadThreadThreadThread {{{{
private private private private CubbyHoleCubbyHoleCubbyHoleCubbyHole cubbyholecubbyholecubbyholecubbyhole;;;;
private private private private intintintint numbernumbernumbernumber;;;;
public public public public ConsumerConsumerConsumerConsumer((((CubbyHoleCubbyHoleCubbyHoleCubbyHole c, c, c, c, intintintint numbernumbernumbernumber) {) {) {) {
cubbyholecubbyholecubbyholecubbyhole = c;= c;= c;= c;
thisthisthisthis....numbernumbernumbernumber = = = = numbernumbernumbernumber;;;;
}}}}
public public public public voidvoidvoidvoid run() {run() {run() {run() {
intintintint valuevaluevaluevalue = 0;= 0;= 0;= 0;
forforforfor ((((intintintint i = 0; i < 10; i++) {i = 0; i < 10; i++) {i = 0; i < 10; i++) {i = 0; i < 10; i++) {
valuevaluevaluevalue = = = = cubbyholecubbyholecubbyholecubbyhole....getgetgetget((((numbernumbernumbernumber););););
}}}}
}}}}
}}}}
Osnova54
public public public public classclassclassclass CubbyHoleCubbyHoleCubbyHoleCubbyHole {{{{
private private private private intintintint contentscontentscontentscontents;;;;
private private private private booleanbooleanbooleanboolean availableavailableavailableavailable = = = = falsefalsefalsefalse;;;;
public synchronized public synchronized public synchronized public synchronized intintintint getgetgetget((((intintintint whowhowhowho) {) {) {) {
whilewhilewhilewhile ((((availableavailableavailableavailable == == == == falsefalsefalsefalse) {) {) {) {
trytrytrytry {{{{
wait();wait();wait();wait();
} } } } catchcatchcatchcatch ((((InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e) { }e) { }e) { }e) { }
}}}}
availableavailableavailableavailable = = = = falsefalsefalsefalse;;;;
SystemSystemSystemSystem....outoutoutout....formatformatformatformat("("("("ConsumerConsumerConsumerConsumer %d %d %d %d gotgotgotgot: %d%n", : %d%n", : %d%n", : %d%n", whowhowhowho, , , , contentscontentscontentscontents););););
notifyAll();notifyAll();notifyAll();notifyAll();
returnreturnreturnreturn contentscontentscontentscontents;;;;
}}}}
public synchronized public synchronized public synchronized public synchronized voidvoidvoidvoid put(put(put(put(intintintint whowhowhowho, , , , intintintint valuevaluevaluevalue) {) {) {) {
whilewhilewhilewhile ((((availableavailableavailableavailable == == == == truetruetruetrue) {) {) {) {
trytrytrytry {{{{
wait();wait();wait();wait();
} } } } catchcatchcatchcatch ((((InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e) { }e) { }e) { }e) { }
}}}}
contentscontentscontentscontents = = = = valuevaluevaluevalue;;;;
availableavailableavailableavailable = = = = truetruetruetrue;;;;
SystemSystemSystemSystem....outoutoutout....formatformatformatformat("("("("ProducerProducerProducerProducer %d put: %d%n", %d put: %d%n", %d put: %d%n", %d put: %d%n", whowhowhowho, , , , contentscontentscontentscontents););););
notifyAll();notifyAll();notifyAll();notifyAll();
}}}}
}}}}
Osnova55
public public public public classclassclassclass ProducerConsumerTestProducerConsumerTestProducerConsumerTestProducerConsumerTest {{{{
public static public static public static public static voidvoidvoidvoid mainmainmainmain((((StringStringStringString argsargsargsargs[]){[]){[]){[]){
CubbyHoleCubbyHoleCubbyHoleCubbyHole c = c = c = c = newnewnewnew CubbyHoleCubbyHoleCubbyHoleCubbyHole();();();();
ProducerProducerProducerProducer p1 = p1 = p1 = p1 = newnewnewnew ProducerProducerProducerProducer(c,1);(c,1);(c,1);(c,1);
ConsumerConsumerConsumerConsumer c1 = c1 = c1 = c1 = newnewnewnew ConsumerConsumerConsumerConsumer(c,1);(c,1);(c,1);(c,1);
p1.start();p1.start();p1.start();p1.start();
c1.start();c1.start();c1.start();c1.start();
}}}}
}}}}
Producer 1 put: 0Producer 1 put: 0Producer 1 put: 0Producer 1 put: 0Consumer 1 got: 0Consumer 1 got: 0Consumer 1 got: 0Consumer 1 got: 0Producer 1 put: 1Producer 1 put: 1Producer 1 put: 1Producer 1 put: 1Consumer 1 got: 1Consumer 1 got: 1Consumer 1 got: 1Consumer 1 got: 1Producer 1 put: 2Producer 1 put: 2Producer 1 put: 2Producer 1 put: 2Consumer 1 got: 2Consumer 1 got: 2Consumer 1 got: 2Consumer 1 got: 2Producer 1 put: 3Producer 1 put: 3Producer 1 put: 3Producer 1 put: 3Consumer 1 got: 3Consumer 1 got: 3Consumer 1 got: 3Consumer 1 got: 3Producer 1 put: 4Producer 1 put: 4Producer 1 put: 4Producer 1 put: 4Consumer 1 got: 4Consumer 1 got: 4Consumer 1 got: 4Consumer 1 got: 4Producer 1 put: 5Producer 1 put: 5Producer 1 put: 5Producer 1 put: 5Consumer 1 got: 5Consumer 1 got: 5Consumer 1 got: 5Consumer 1 got: 5Producer 1 put: 6Producer 1 put: 6Producer 1 put: 6Producer 1 put: 6Consumer 1 got: 6Consumer 1 got: 6Consumer 1 got: 6Consumer 1 got: 6Producer 1 put: 7Producer 1 put: 7Producer 1 put: 7Producer 1 put: 7Consumer 1 got: 7Consumer 1 got: 7Consumer 1 got: 7Consumer 1 got: 7Producer 1 put: 8Producer 1 put: 8Producer 1 put: 8Producer 1 put: 8Consumer 1 got: 8Consumer 1 got: 8Consumer 1 got: 8Consumer 1 got: 8Producer 1 put: 9Producer 1 put: 9Producer 1 put: 9Producer 1 put: 9Consumer 1 got: 9Consumer 1 got: 9Consumer 1 got: 9Consumer 1 got: 9
56
Deadlock - uváznutí
• Uváznutí se týká vzájemné závislosti dvou vláken např.
• jedno vlákno provádí kód, který je synchronizovaný daným objektem (tenObjekt)
• pak má provést další metodu synchronizovanou jiným objektem (jinyObjekt)
• než k tomu dojde, druhé vlákno provede kód synchronizovaný jinyObjekt a potřebuje provést metodu obsahující kód synchronizovaný prvním objektem (tenObjekt)
• žádné vlákno nemá možnost pokračovat, oběuvázla
Osnova57
classclassclassclass DeadlockExDeadlockExDeadlockExDeadlockEx {{{{
public static public static public static public static voidvoidvoidvoid mainmainmainmain( ( ( ( StringStringStringString[ ] [ ] [ ] [ ] argsargsargsargs ) {) {) {) {
newnewnewnew MyThreadMyThreadMyThreadMyThread( "( "( "( "foofoofoofoo" ).start();" ).start();" ).start();" ).start();
newnewnewnew MyThreadMyThreadMyThreadMyThread( "bar" ).start();( "bar" ).start();( "bar" ).start();( "bar" ).start();
}}}}
}}}}
classclassclassclass MyThreadMyThreadMyThreadMyThread extendsextendsextendsextends ThreadThreadThreadThread {{{{
public public public public MyThreadMyThreadMyThreadMyThread( ( ( ( StringStringStringString namenamenamename ) { super( ) { super( ) { super( ) { super( namenamenamename ); }); }); }); }
public public public public voidvoidvoidvoid run() {run() {run() {run() {
whilewhilewhilewhile ( ( ( ( truetruetruetrue ))))
ifififif ( ( ( ( getNamegetNamegetNamegetName().().().().equalsIgnoreCaseequalsIgnoreCaseequalsIgnoreCaseequalsIgnoreCase( "( "( "( "foofoofoofoo" ) )" ) )" ) )" ) )
fooMfooMfooMfooM();();();();
elseelseelseelse
barMbarMbarMbarM();();();();
}}}}
private synchronized private synchronized private synchronized private synchronized voidvoidvoidvoid fooMfooMfooMfooM() {() {() {() {
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( ( ( ( getNamegetNamegetNamegetName() + " vstup () + " vstup () + " vstup () + " vstup fooMfooMfooMfooM." );." );." );." );
whilewhilewhilewhile ( ( ( ( getNamegetNamegetNamegetName().().().().equalsIgnoreCaseequalsIgnoreCaseequalsIgnoreCaseequalsIgnoreCase( "bar" ) )( "bar" ) )( "bar" ) )( "bar" ) )
trytrytrytry {{{{
wait(); // wait(); // wait(); // wait(); // cekanicekanicekanicekani na na na na neurcitoneurcitoneurcitoneurcito
} } } } catchcatchcatchcatch( ( ( ( InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e ) { }e ) { }e ) { }e ) { }
barMbarMbarMbarM(); // (); // (); // (); // vyvolavyvolavyvolavyvola jinou jinou jinou jinou synchronizacnisynchronizacnisynchronizacnisynchronizacni metodumetodumetodumetodu
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( ( ( ( getNamegetNamegetNamegetName() + " vystup () + " vystup () + " vystup () + " vystup fooMfooMfooMfooM." );." );." );." );
notifynotifynotifynotify(); // (); // (); // (); // vzbudivzbudivzbudivzbudi jinejinejinejine vlaknovlaknovlaknovlakno, pokud , pokud , pokud , pokud nejakenejakenejakenejake cekacekacekaceka
}}}}
Osnova58
private synchronized private synchronized private synchronized private synchronized voidvoidvoidvoid barMbarMbarMbarM() {() {() {() {
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( ( ( ( getNamegetNamegetNamegetName() + " vstup () + " vstup () + " vstup () + " vstup barMbarMbarMbarM." );." );." );." );
whilewhilewhilewhile ( ( ( ( getNamegetNamegetNamegetName().().().().equalsIgnoreCaseequalsIgnoreCaseequalsIgnoreCaseequalsIgnoreCase( "( "( "( "foofoofoofoo" ) )" ) )" ) )" ) )
trytrytrytry {{{{
wait(); // wait(); // wait(); // wait(); // cekanicekanicekanicekani na na na na neurcitoneurcitoneurcitoneurcito
} } } } catchcatchcatchcatch( ( ( ( InterruptedExceptionInterruptedExceptionInterruptedExceptionInterruptedException e ) { }e ) { }e ) { }e ) { }
fooMfooMfooMfooM(); // (); // (); // (); // vyvolavyvolavyvolavyvola jinou jinou jinou jinou synchronozacnisynchronozacnisynchronozacnisynchronozacni metodu metodu metodu metodu
SystemSystemSystemSystem....outoutoutout....printlnprintlnprintlnprintln( ( ( ( getNamegetNamegetNamegetName() + " vystup () + " vystup () + " vystup () + " vystup barMbarMbarMbarM." );." );." );." );
notifynotifynotifynotify(); // (); // (); // (); // vzbudivzbudivzbudivzbudi jinejinejinejine vlaknovlaknovlaknovlakno, pokud , pokud , pokud , pokud nejakenejakenejakenejake cekacekacekaceka
}}}}
}}}}
foofoofoofoo vstup vstup vstup vstup fooMfooMfooMfooM....
bar vstup bar vstup bar vstup bar vstup barMbarMbarMbarM....
foofoofoofoo vstup vstup vstup vstup barMbarMbarMbarM....
bar vstup bar vstup bar vstup bar vstup fooMfooMfooMfooM....
59
Uváznutí
• Problémem uváznutí jsou vztahy mezi metodami wait(), notify() a notofyAll(). Metoda wait() musípředcházet metodu notify(). Pokud je tomu naopak, vlákno nemůže být probuzeno.
• V uvedeném programu vlákno foo vykonávásynchronizovanou nejdříve metodu fooM() a potésynchronizovanou metodu barM(). Vlákno bar vykoná nejdříve synchronizovanou metodu barM() a potom synchronizovanou metodu fooM(). Avšak každé vlákno čeká v metodě jména svého protějšku. Vlákno foo čeká v metoděbarM() a vlákno bar čeká v metodě fooM().
60
Uváznutí
• Vlákno foo získá zámek na barM a čeká. Vlákno foo může být probuzeno pouze vláknem bar, kterévyvolá metodu notify() v metodě barM().
• Vlákno foo nezíská zámek na barM() protože vlákno bar má aktuálně tento zámek. Dokud vlákno foo nezíská tento zámek, bude čekat.
61
Nejdůležit ější konstruktory t řídy Thread
Pojmenované vlákno se specifikovaným běhuschopným cílem.
Thread(Runnable t, String s);
Nepojmenované vlákno se specifikovaným běhuschopným cílem.
Thread(Runnabletarget);
Pojmenované vlákno s defóltním běhuschopnýmcílem.
Thread(String s);
Nepojmenované vlákno s defóltnímběhuschopným cílem.
Thread();
PopisDeklarace
62
Třídní metody t řídy Thread
Uspí běžící (current) vlákno na n milisekund.
void sleep(long n);
Testuje, zda běžící vlákno (current) mápříznak interrupted.
boolean interrupted();
Vrací odkaz na právě běžící vlákno (current).
Thread currentThread();
PopisDeklarace