بسم الله الرحمن الرحيم
Java Thread
دانشگاه بوعلي سينا
دانشکده مهندسي
مهدي سخائي نيا گروه كامپيوتر
[email protected]
[email protected]
نيمسال دوم
سال تحصيلي 1385-86
Thread Termination (1)
• It completes execution of its run method either normally دانشگاه بوعلي سينا
دانشکده مهندسي
or as the result of an unhandled exception. گروه كامپيوتر
• Its destroy method is called (either by another thread or
by itself) — destroy terminates the thread without the
thread object having any chance to cleanup.
– Note, however, this method is not provided in many
implementations of the Java virtual machine. As of Java
1.5, it has finally been deprecated.
2
Thread Termination (2)
• Its stop method is called (again by another thread or by دانشگاه بوعلي سينا
دانشکده مهندسي
itself). گروه كامپيوتر
– The thread class is able to clean up (releases the locks it
holds and executes any finally clauses) before
terminating the thread.
– The stop methods are inherently unsafe as they release
locks on objects and can leave those objects in
inconsistent states. For this reason, the methods are now
deprecated and, therefore, should not be used.
3
Java Thread Types
• user threads دانشگاه بوعلي سينا
دانشکده مهندسي
• daemon threads گروه كامپيوتر
– Daemon threads are those threads that provide general
services and typically never terminate.
– Hence when all user threads have terminated, daemon
threads can also be terminated, and the main program
terminates.
– By default, threads are user threads
– Calling the setDaemon method with a true parameter
indicates that the thread is a daemon.
– Note the setDaemon method must be called before any
such thread is started
Thread t = new Thread(r);
t.setDaemon(true);
t.start(); 4
wait for the termination of the
another thread
• One thread can wait (with or without a timeout) for دانشگاه بوعلي سينا
دانشکده مهندسي
another thread (the target) to terminate by issuing the join گروه كامپيوتر
method call on the target's thread object.
• Furthermore, the isAlive method allows a thread to
determine if the target thread has terminated.
• The specifications of the above methods are shown below
package java.lang;
public class Thread extends Object implements Runnable { ...
public void destroy(); // DEPRECATED
public final boolean isAlive();
public final boolean isDaemon();
public final void join () throws InterruptedException;
public final void join(long millis) throws InterruptedException;
public final void join (long millis, int nanos) throws InterruptedException;
public final void setDaemon(boolean on);
public final void stop(); // DEPRECATED 5
public final void stop (Throwable o); // DEPRECATED ... }
Thread-local Data (1)
• Java provides two types of data: دانشگاه بوعلي سينا
دانشکده مهندسي
– Static data declared in a class is shared between all instances گروه كامپيوتر
of the class.
– Nonstatic data, in contrast, is replicated in all instances of the
class.
• Consider a class that is defined as follows:
public class withStaticData {
public static int shared;
public int notShared;
}
If two objects of this class are created, say 01 and 02, then it will
always be the case that at any point in time
• 01.shared == 02.shared == withStatic.shared
• However, there will be two notShared variables: 01.notShared and
02.notShared. Consequently, there is no guarantee that 01.notShared
will ever equal 02.notShared 6
Thread-local Data (2)
• For multithreaded applications where objects with local دانشگاه بوعلي سينا
دانشکده مهندسي
data may be called by more than one thread, a third type گروه كامپيوتر
of data is often required. This is data that is shared within
the same thread but that is different across threads.
• This is achieved by a special type of object called a
thread-local object.
• If a thread-local object is declared as static, then the
object holds a different value for each thread that uses the
object. Thread-local objects are created from the
ThreadLocal class. (This class has been made generic as
of Java 1.5.)
7
Thread-local Data (3)
• Now the class: دانشگاه بوعلي سينا
دانشکده مهندسي
public class withStaticData { گروه كامپيوتر
...
public static ThreadLocal threadSharedClass;
public ThreadLocal threadSharedObject;
}
will have one copy of threadSharedClass per thread
that uses the class, whereas threadSharedObject will
have one copy per thread per instance of the class
withStaticData
8
Thread-local Data (4) - Example
• a secure server that requires a client to log in before دانشگاه بوعلي سينا
دانشکده مهندسي
allowing it to call its methods. گروه كامپيوتر
• The login method returns a password that must be
presented by the thread each time it issues a method
call.
• Now the server could save a mapping between threads
and passwords.
• However, this is tedious and error prone.
• Thread-local data provides a simple and elegant
solution.
9
Thread-local Data (5) - Example
public class Password { دانشگاه بوعلي سينا
public Password(); // Generates a new password. دانشکده مهندسي
public String getPassword(); // Returns the password. گروه كامپيوتر
public boolean match(String pass) // Returns true if pass is the password.
}
public class SecureService {
private ThreadLocal password = new ThreadLocal();
public String login() {
Password pass = new Password();
password.set(pass);
return pass.getPassword();
}
public void service(String pass) throws Exception {
Password check = (Password) password.get();
if(check.match(pass)) { // perform service }
else throw new Exception("no access allowed");
10
}
}
Thread-local Data (6)
دانشگاه بوعلي سينا
package java.lang; دانشکده مهندسي
public class ThreadLocal<T> { گروه كامپيوتر
// constructor
public ThreadLocal();
// methods
public T get();
public void set (T value);
protected T initialValue();
public void remove();
// This method is a Java 1.5 addition, it clears
// the value for the thread local.
}
11
سنكرون سازي ()1
• چرا سنكرون سازي؟ دانشگاه بوعلي سينا
دانشکده مهندسي
– نياز دو يا بيشتر Threadبه* يك منبع مشترك. گروه كامپيوتر
• سنكرون سازي ,چگونه؟
– با استفاده از Monitor
• مانيتور در جاوا :
– مانيتور ,شيئي است كه به صورت يك قفل انحصاري يا MUTEXمورد
استفاده قرار مي گيرد.
12
سنكرون سازي ()2
• تمام اشياء داراي مانيتور ضمني هستند. دانشگاه بوعلي سينا
دانشکده مهندسي
گروه كامپيوتر
• براي ورود به مانيتور هر شيء كافي است متدي را كه با كلمه كليدي
synchronizedمشخص شده فراخواني گردد.
• مادامي كه يك threadدر متد سنكرون شده اي قرار داردthread ,
هاي ديگري كه بخواهند آنرا با همان نمونه شي فرا بخوانند ,بايد
منتظر بمانند.
• انتقال كنترل شي به threadبعدي در حال انتظار ,با پايان يافتن متد
سنكرون شده صورت مي گيرد.
13
سنكرون سازي ( - )3مثال
دانشگاه بوعلي سينا
دانشکده مهندسي
گروه كامپيوتر
• به مثال Synch.javaنگاه كنيد.
14
سنكرون سازي ()4
سنكرون سازي با اين روش هميشه ممكن نيست : • دانشگاه بوعلي سينا
دانشکده مهندسي
– اشيايي براي دستيابي multithreadطراحي نشده اند( كلمه گروه كامپيوتر
synchronizedندارند
– به كد منبع يك كالس* دسترسي نداريم.
راه حل : •
– استفاده از بالك synchronized
{ ) Synchronized( object
// statements to be synchronized
}
ش**يئي*س*تك*ه س**نكرو*نم*يش**ود .ب**لوك*ه*ايس**نكرو*ن
ا Objectار*جاع ب**ه –
*ت
ش**ده* ت**ضمينم*يك*نند ك*ه ف**را*خوا*ن*يم*تديك*ه ع*ضوياز objectا*س ,
*قيت*م*يز threadج*ار*يب**ه م*ان*يتور objectر*خ
ت**نه*ا پ**ساز ورود م*وف آ
م*يدهد. 15
سنكرون سازي ()5
دانشگاه بوعلي سينا
دانشکده مهندسي
گروه كامپيوتر
• به مثال Synch1.javaنگاه كنيد.
16
ارتباط بين threadها
• ارتباط threadها بجاي سنكرون سازي با استفاد از synchronized دانشگاه بوعلي سينا
دانشکده مهندسي
گروه كامپيوتر
• : PollingمUعموال بUUوسUيله حUلقه پUUيادUه UسUازUيمUيشUود كUه بUUراUي
بUUررUسUيمUكرر شUراUيUطمUورد نUUظر بUUكار مUيرود.
سUببتUالفوUقUت cpuمUيگUUردد.
اU • Polling
• در ارتباط بين threadها در جاوا pollingحذف مي گردد.
17
مكانيزم ارتباط ()1
دانشگاه بوعلي سينا
دانشکده مهندسي
• جاوا براي اجتناب از pollingمكانيزم ارتباط بين threadها را از گروه كامپيوتر
طريق متدهاي wait , notifyو notifyallفراهم ساخته است.
• تمام كالسها به آن دسترسي دارند
– چون اين متدها بصورت finalدر objectپياده سازي شده اند.
• اين سه متد بايد بصورت synchronizedفراخواني گردند.
18
مكانيزم ارتباط ()2
دانشگاه بوعلي سينا
دانشکده مهندسي
• – )(waitبUUراUي threadفUراUخواUنمUشخصمUيكUند كUه كUنترلمUانUيتور گروه كامپيوتر
را واUگذار نUUمايد و تUUا ورود يUك threadدUيUگر بUUه هUمانمUانUيتور و
فUراUخواUنUي notifyدر وUضUعيتتUUعليققUرار گUUيرد.
– final void wait () throws InterruptedException
شUي فUرا خUواUندهU
• notify() – ThraedاUيرا كUه waitرا بUUراUيهUمان ء
Uتاز وUضUعيتتUUعليقخUارUج مUيسUازد.
اUس ,
)(– final void notify
شUي
• – )(notifyallتUUمام threadهايUيرا كUه waitرا بUUراUيهUمان ء
فUراUخواUنده UاUند ,از وUضUعيتتUUعليقخUارUج مUيسUازد .مUجوز دUسUتيابUيبUUه
يUكياز threadهااUعطا مUيشUود.
)(– final void notifyall 19
)1( مسئله توليد كننده – مصرف كننده
class Q { دانشگاه بوعلي سينا
دانشکده مهندسي
int n; گروه كامپيوتر
synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n = n;
System.out.println("Put: " + n);
}
}
20
)2( مسئله توليد كننده – مصرف كننده
class Producer implements Runnable { دانشگاه بوعلي سينا
Q q; دانشکده مهندسي
گروه كامپيوتر
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
} 21
)3( مسئله توليد كننده – مصرف كننده
class Consumer implements Runnable { دانشگاه بوعلي سينا
دانشکده مهندسي
Q q; گروه كامپيوتر
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
} 22
)4( مسئله توليد كننده – مصرف كننده
دانشگاه بوعلي سينا
class PC { دانشکده مهندسي
public static void main(String args[]) گروه كامپيوتر
{
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C
to stop.");
}
}
23
class Q {
int n;
)1( حل مشكل
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
try {
wait(); دانشگاه بوعلي سينا
دانشکده مهندسي
} catch(InterruptedException e) { گروه كامپيوتر
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
if(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
24
valueSet = true;
System.out.println("Put: " + n);
notify();
}
)2( حل مشكل
class Producer implements Runnable { دانشگاه بوعلي سينا
Q q; دانشکده مهندسي
گروه كامپيوتر
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
} 25
)3( حل مشكل
class Consumer implements Runnable { دانشگاه بوعلي سينا
دانشکده مهندسي
Q q; گروه كامپيوتر
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
} 26
)4( حل مشكل
دانشگاه بوعلي سينا
class PCFixed { دانشکده مهندسي
public static void main(String args[]) گروه كامپيوتر
{
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C
to stop.");
}
}
27
)1( نكاتي ديگر
package java.lang; دانشگاه بوعلي سينا
دانشکده مهندسي
public class Object { گروه كامپيوتر
...
// The following methods all throw the
unchecked
// IllegalMonitorStateException.
public final void notify();
public final void notifyAll();
public final void wait() throws
InterruptedException;
public final void wait(long millis) throws
InterruptedException;
nanos) throws InterruptedException; ... } 28
public final void wait(long millis, int
)2( نكاتي ديگر
• These methods are designed to be used only from دانشگاه بوعلي سينا
دانشکده مهندسي
within methods that hold the object lock (that is, they گروه كامپيوتر
are synchronized).
• If called without the lock, the exception
IllegalMonitorStateException is thrown
• The wait method always blocks the calling thread and
releases the lock associated with the object.
• If a thread is holding several locks (for example, in a
nested monitor call), only the lock associated with the
object being waited on is released. All other locks are
maintained. 29
)3( نكاتي ديگر
• The notify method wakes up one waiting thread; the دانشگاه بوعلي سينا
دانشکده مهندسي
one woken is not defined by the Java language گروه كامپيوتر
(however, it is defined by the RTSJ).
• Note that notify does not release the lock, and hence
the woken thread must still wait until it can obtain the
lock before it can continue.
• To wake up all waiting threads requires use of the
notifyAll method; again this does not release the
lock, and all the awoken threads must wait and
contend for the lock when it becomes free.
• If no thread is waiting, then notify and notifyAll
have no effect.
30
بن بست
دانشگاه بوعلي سينا
دانشکده مهندسي
• دو threadكه وارد دو شيء سنكرون شده اند ,متدي ديگر كه گروه كامپيوتر
synchronizedشده در شيء مقابل را فراخواني نمايند.
31
class A { دانشگاه بوعلي سينا
synchronized void foo(B b) { دانشکده مهندسي
String name = Thread.currentThread().getName(); گروه كامپيوتر
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("A Interrupted");
}
System.out.println(name + " trying to call B.last()");
b.last();
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
32
class B { دانشگاه بوعلي سينا
synchronized void bar(A a) { دانشکده مهندسي
String name = Thread.currentThread().getName(); گروه كامپيوتر
System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying to call A.last()");
a.last();
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
33
class Deadlock implements Runnable { دانشگاه بوعلي سينا
A a = new A(); دانشکده مهندسي
B b = new B(); گروه كامپيوتر
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
a.foo(b); // get lock on a in this thread.
System.out.println("Back in main thread");
}
public void run() {
b.bar(a); // get lock on b in other thread.
System.out.println("Back in other thread");
}
public static void main(String args[]) {
new Deadlock();
}
34
}