|
|
See also: here.
Java programs, applications, and applets can consists of threads which conceptually are executed in parallel. This section demonstrates with simple examples how threads are created and manipulated, how exclusive access to common variables is managed, how conditional access is obtained, and how threads are connected with pipelines. Two classical examples concern communication with semaphores and conditional access to resources.
The Thread java doc page: here.
Why two different ways?
public interface Runnable {
public abstract void run();
}
The first example:
public class Thread_1 extends Thread {
private String info;
int x = 0;
public Thread_1 (String info) {
this.info = info;
}
public void run () {
x=1;
System.out.print(info);
}
public static void main (String args []) {
if (args != null)
for (int n = 0; n < args.length; ++ n) {
Thread_1 aT1 = new Thread_1(args[n]);
if ( n % 2 == 0 )
aT1.setPriority(Thread.MIN_PRIORITY);
aT1.start();
}
}
}
Source Code: Src/11/Thread_1.java
Result:
% java Thread_1 a b c d e f g h i j k l m n o p q r s bdfhjlnpracegikmoqs%
Second Example:
public class Thread_2 extends Thread {
private String info;
public Thread_2 (String info) {
this.info = info;
}
public void run () {
long sleep = (int)(Math.random() * 10000);
System.out.println(info + " sleeps for " + sleep );
try {
sleep(sleep);
}
catch ( InterruptedException e ) {
e.getMessage();
}
}
public static void main (String args []) {
int count = 0;
if (args != null)
for (int n = 0; n < args.length; ++ n) {
Thread_2 aT1 = new Thread_2(args[n]);
if ( n % 2 == 0 )
aT1.setPriority(Thread.MIN_PRIORITY);
aT1.start();
}
while ( count != 1 ) {
try {
count = activeCount();
System.out.println("activeCount() = " +
count );
sleep(500);
}
catch ( InterruptedException e ) {
e.getMessage();
}
}
}
}
Source Code: Src/11/Thread_2.java
java Thread_2 a b c d activeCount() = 5 b sleeps for 1063 d sleeps for 8295 a sleeps for 2197 c sleeps for 2619 activeCount() = 5 activeCount() = 5 activeCount() = 4 activeCount() = 4 activeCount() = 3 activeCount() = 2 .. activeCount() = 2 activeCount() = 1
The execution of the Java Virtual Machine ends once most threads reach the end of their run() methods. ``Most'' means that there are user and daemon threads and thread groups; execution of the JVM ends when there are no more user threads. The distinction is made by calling setDaemon() ; the distinction is necessary, because threads that deliver events and manage painting in a window system are irrelevant for deciding if an application has completed it's job
public class Thread_3 extends Thread {
private String info;
Thread_3 aT1;
public Thread_3 (String info) {
this.info = info;
}
public void run () {
System.out.println(info + " is running");
try {
sleep(1000000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
if ( isInterrupted() )
System.err.println("yup it's true.");
}
System.out.println(info + ": exit run");
}
public static void main (String args []) {
Thread_3 aT1 = new Thread_3("first");
aT1.start();
System.err.println("interrupt 'first'");
aT1.interrupt();
}
}
Source Code: Src/11/Thread_3.java
Result:
% java Thread_3 first is running interrupt 'first' Interrupted! first: exit run
Extract from Javadoc:
The interrupted status of the current thread is cleared when this exception is thrown.
public class Join extends Thread {
private String info;
Join aT1;
public Join (String info) {
this.info = info;
}
public void run () {
System.out.println(info + " is running");
try {
sleep(10);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
if ( isInterrupted() )
System.err.println("yup it's true.");
}
System.out.println(info + ": exit run");
}
public static void main (String args []) {
Join aT1 = new Join("first");
aT1.start();
try {
aT1.join();
System.err.println("Got it");
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
}
}
Source Code: Src/11/Join.java
Result:
% java Join first is running first: exit run Got it
Extract from Javadoc:
The interrupted status of the current thread is cleared when this exception is thrown.
import java.util.*;
public class Thread_R implements Runnable {
private String name;
private Vector aVector;
public Thread_R (String name) {
this.name = name;
}
public void run () {
System.out.println("Hi :) ... my name is: " + name );
}
public static void main (String args []) {
String names[] = { "Franz", "Rosemarie", "Wolfgang",
"Uwe", "Urte"
};
for ( int index = 0; index < names.length; index ++ ) {
new Thread( new Thread_R( names[index] ) ).start();
}
}
}
Source Code: Src/11/Thread_R.java
Threads can obtain exclusive access to an object if all competing threads use a synchronized statement or call a method with synchronized attribute. Class methods monitor the class description, other methods monitor their receiver, the statement monitors the indicated value. The attribute synchronized precedes the result type.
Adding or deleting a synchronized modifier of a method does not break compatibility with existing binaries.
public synchronized method( ...) { ... }
synchronized(aObj) { ... }
public synchronized method( ...) { ... }
is aequivalent to
public method( ...) {
synchronized ( this ) {
}
}
Note: Interface methods can't be native, static, synchronized, final, private, or protected
Wrong:
import java.util.*;
public class Thread_4 extends Thread {
private String info;
private Vector aVector;
public Thread_4 (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
private synchronized void inProtected () {
System.err.println(info + ": is in protected()");
aVector.addElement(info);
try {
if ( info.equals("second") )
sleep(1000);
else
sleep(3000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println(info + ": exit run");
}
public void run () {
inProtected();
}
public static void main (String args []) {
Vector aVector = new Vector();
Thread_4 aT4_0 = new Thread_4("first", aVector);
Thread_4 aT4_1 = new Thread_4("second", aVector);
aT4_0.start();
aT4_1.start();
}
}
Source Code: Src/11/Thread_4.java
Result:
% java Thread_4 first: is in protected() second: is in protected() second: exit run first: exit run
Correct:
import java.util.*;
public class Protected extends Thread {
private String info;
public Protected (String info) {
this.info = info;
}
public synchronized void inProtected (String i) {
System.err.println("\t" + i + ": is in protected()");
try {
sleep(300);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("\t" + i + ": exit run");
}
public void run () {
while ( true ) {
System.err.println("Protected!run: try to execute " +
"inProtected(" + info + ")");
inProtected(info);
System.err.println("Protected!run" + ": back ");
}
}
}
Source Code: Src/11/Protected.java
import java.util.*;
public class UseProtected extends Thread {
private Protected aPobject;
public UseProtected (Protected aPobject) {
this.aPobject = aPobject;
}
public void run () {
while (true ) {
try {
sleep(1000);
System.err.println(
"UseProtected!run: try to execute " +
" inProtected(UseProtected)");
aPobject.inProtected("UseProtected");
System.err.println("UseProtected: back.");
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
}
}
public static void main (String args []) {
Protected aPobject = new Protected("Protected!");
aPobject.start();
new UseProtected(aPobject).start();
try {
sleep(10000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
}
}
Source Code: Src/11/UseProtected.java
Result:
yps 11 107 java UseProtected
java UseProtected
Protected!run: try to execute inProtected(Protected!)
Protected!: is in protected()
Protected!: exit run
Protected!run: back
Protected!run: try to execute inProtected(Protected!)
Protected!: is in protected()
Protected!: exit run
Protected!run: back
Protected!run: try to execute inProtected(Protected!)
Protected!: is in protected()
Protected!: exit run
Protected!run: back
Protected!run: try to execute inProtected(Protected!)
Protected!: is in protected()
UseProtected!run: try to execute inProtected(UseProtected)
^C
import java.util.*;
public class M extends Thread {
private String info;
private Vector aVector;
public M (String info) {
this.info = info;
}
private synchronized void inProtected () {
System.err.println(info + ": is in protected()");
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println(info + ": exit run");
}
public void run () {
inProtected();
}
public static void main (String args []) {
Vector aVector = new Vector();
M aT4_0 = new M("first");
aT4_0.start();
aT4_0.inProtected();
}
}
Source Code: Src/11/M.java
first: is in protected() first: exit run first: is in protected() first: exit run
import java.util.*;
public class Thread_5 extends Thread {
private String info;
private Vector aVector;
public Thread_5 (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
public void inProtected () {
synchronized ( aVector ) {
System.err.println(info + ": is in protected()");
try {
if ( info.equals("second") )
sleep(1000);
else
sleep(3000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println(info + ": exit run");
}
}
public void run () {
inProtected();
}
public static void main (String args []) {
Vector aVector = new Vector();
Thread_5 aT5_0 = new Thread_5("first", aVector);
Thread_5 aT5_1 = new Thread_5("second", aVector);
aT5_0.start();
aT5_1.start();
}
}
Source Code: Src/11/Thread_5.java
Result:
% java Thread_5 first: is in protected() first: exit run second: is in protected() second: exit run
import java.util.*;
public class ClassT extends Thread {
private String info;
private Vector aVector;
public ClassT (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
static synchronized void staticInProtected1(String s) {
System.err.println(s + ": ---->");
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
staticInProtected2(s);
System.err.println(s + ": <----");
}
static synchronized void staticInProtected2(String s) {
System.err.println(s + ": ====>");
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println(s + ": ====>");
}
public void run () {
staticInProtected1(info);
}
public static void main (String args []) {
Vector aVector = new Vector();
ClassT aClassT_0 = new ClassT("first", aVector);
ClassT aClassT_1 = new ClassT("second", aVector);
ClassT.staticInProtected1("main");
aClassT_0.start();
aClassT_1.start();
aClassT_0.staticInProtected1("aClassT_0");
aClassT_1.staticInProtected1("aClassT_1");
}
}
Source Code: Src/11/ClassT.java
Result:
% java ClassT main: ----> main: ====> main: ====> main: <---- aClassT_0: ----> aClassT_0: ====> aClassT_0: ====> aClassT_0: <---- aClassT_1: ----> aClassT_1: ====> aClassT_1: ====> aClassT_1: <---- first: ----> first: ====> first: ====> first: <---- second: ----> second: ====> second: ====> second: <----
One more:
import java.util.*;
public class Thread_6 extends Thread {
private String info;
private Vector aVector;
public Thread_6 (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
private void inProtected_1 () {
synchronized ( aVector ) {
System.err.println("1: " + info + ": is in ");
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("1: " + info + ": exit");
}
}
private void inProtected_2 () {
synchronized ( info ) {
System.err.println("2: " + info + ": is IN ");
try {
sleep(5000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("2: " + info + ": EXIT");
}
}
private static void inProtected_3 () {
System.err.println("3: IN ");
try {
sleep(9000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("3: EXIT");
}
public void run () {
inProtected_1();
inProtected_2();
Thread_6.inProtected_3();
}
public static void main (String args []) {
Vector aVector = new Vector();
Thread_6 aT6_0 = new Thread_6("first", aVector);
Thread_6 aT6_1 = new Thread_6("second", aVector);
aT6_0.start();
aT6_1.start();
}
}
Source Code: Src/11/Thread_6.java
By using wait and notify a thread can give up its lock at an abratiary point and the wait for another thread to give it back for continuation.
import java.util.Vector;
public class WaitAndNotify extends Thread {
private String info;
static Vector aVector = new Vector();
public WaitAndNotify (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
public void doTheJob() {
synchronized ( aVector ) {
if ( info.equals("last") ) {
System.out.println(info + " is waking up ...");
aVector.notifyAll();
System.out.println(info + " done.");
} else {
System.out.println(info + " is waiting");
try {
aVector.wait();
} catch ( IllegalMonitorStateException e ) {
System.out.println(info +
": IllegalMonitorStateException");
} catch ( InterruptedException e ) {
System.out.println(info +
": InterruptedException");
}
System.out.println(info + " is awake!");
}
}
}
public void run () {
doTheJob();
}
public static void main (String args []) {
new WaitAndNotify("first", aVector).start();
new WaitAndNotify("second", aVector).start();
new WaitAndNotify("last", aVector).start();
}
}
Source Code: Src/11/WaitAndNotify.java
Result:
% java WaitAndNotify first is waiting second is waiting last is waking up ... last done. first is awake! second is awake!
import java.util.Vector;
public class WaitAndNotify_2 extends Thread {
private String info;
static Integer monitor = new Integer(3);
static int count = 0;
static int max = 0;
public WaitAndNotify_2 (String info) {
this.info = info;
// max ++;
}
public void doTheJob() {
synchronized ( monitor ) {
System.out.println(info + " is waiting");
count ++;
// if ( count == max );
if ( count == 3 )
monitor.notifyAll();
else
try {
monitor.wait();
sleep(1000);
} catch ( Exception e ) {
System.out.println(info +
": IllegalMonitorStateException");
}
System.out.println(info + " is awake!");
}
}
public void run () {
doTheJob();
}
public static void main (String args []) {
new WaitAndNotify_2("first").start();
new WaitAndNotify_2("second").start();
new WaitAndNotify_2("last").start();
}
}
Source Code: Src/11/WaitAndNotify_2.java
Result:
% java WaitAndNotify_2 first is waiting second is waiting last is waiting last is awake! first is awake! second is awake!
import java.util.Vector;
import java.util.Date;
public class WaitAndNotify_3 extends Thread {
private String info;
static Vector aVector = new Vector();
public WaitAndNotify_3 (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
public void doTheJob() {
synchronized ( aVector ) {
System.out.println(info + " is waiting. " + new Date() );
try {
aVector.wait(1000);
} catch ( Exception e ) {
System.out.println(info + ": Exception");
e.printStackTrace();
}
System.out.println(info + " is awake! " + new Date());
}
}
public void run () {
doTheJob();
}
public static void main (String args []) {
new WaitAndNotify_3("first", aVector).start();
new WaitAndNotify_3("second", aVector).start();
// new WaitAndNotify_3("last", aVector).start();
}
}
Source Code: Src/11/WaitAndNotify_3.java
% java WaitAndNotify_3 first is waiting. Mon Apr 16 15:02:10 EDT 2001 second is waiting. Mon Apr 16 15:02:11 EDT 2001 first is awake! Mon Apr 16 15:02:12 EDT 2001 second is awake! Mon Apr 16 15:02:12 EDT 2001 %
/*
* is this output --->
* <--
* ...
* the only possible output?
*/
public class T_1 extends Thread {
String info;
public T_1(String info ) {
this.info = info;
}
private synchronized void inProtected () {
System.err.println("--> " + info);
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("<-- " + info);
}
public void run () {
inProtected();
}
public static void main (String args []) {
new T_1("1").start();
new T_1("2").start();
new T_1("3").start();
}
}
Source Code: Src/Question_Week_5/T_1.java
/*
* is this output --->
* <--
* ...
* the only possible output?
*/
public class T_2 extends Thread {
private static String info;
public T_2(String info ) {
this.info = info;
}
private void inProtected () {
synchronized ( info ) {
System.err.println("--> " + info);
try {
sleep(1000);
} catch ( Exception e ) {
e.printStackTrace();
}
System.err.println("<-- " + info);
}
}
public void run () {
inProtected();
}
public static void main (String args []) {
String a = "hello";
new T_2(a).start();
new T_2(a).start();
}
}
Source Code: Src/Question_Week_5/T_2.java
/*
* is this output --->
* <--
* ...
* the only possible output?
*/
public class T_3 extends Thread {
private int info;
public T_3 (int info) {
this.info = info;
}
public synchronized void run () {
System.err.println("--> " + info);
try {
sleep(1000);
} catch ( Exception e ) {
e.printStackTrace();
}
System.err.println("<-- " + info);
}
public static void main (String args []) {
for ( int i = 1; i < 100; i ++ )
new T_3(i).start();
}
}
Source Code: Src/Question_Week_5/T_3.java
/*
* is this output --->
* <--
* ...
* the only possible output?
*/
public class T_4 extends Thread {
static Object o = new Object();
String info;
public T_4(String info ) {
this.info = info;
}
public void run () {
synchronized ( o ) {
System.err.println("--->" + info);
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("<---" + info);
}
}
public static void main (String args []) {
new T_4("1").start();
new T_4("2").start();
new T_4("3").start();
}
}
Source Code: Src/Question_Week_5/T_4.java
public class T_5 extends Thread {
static String i = "2";
T_5(String i) {
this.i = i;
}
public void run () {
if ( this.i.equals("1") )
i = "3";
else
i = "4";
}
public static void main (String args []) {
T_5 aT_5 = new T_5("1");
aT_5.start();
aT_5.run();
System.out.println("aT_5.i = " + aT_5.i );
System.out.println(aT_5.i + " = " + aT_5.i );
}
}
Source Code: Src/Question_Week_5/T_5.java
public class T_6 extends Thread {
static String i = null;
T_6(String i) {
this.i = i;
}
public synchronized void run () {
if ( this.i.equals("1") )
i = "3";
else
i = "4";
}
public static void main (String args []) {
T_6 aT_6 = new T_6("1");
aT_6.start();
aT_6.run();
System.out.println("aT_6.i = " + aT_6.i );
}
}
Source Code: Src/Question_Week_5/T_6.java
public class T_7 extends Thread {
static String i = null;
T_7(String i) {
this.i = i;
}
public void run () {
if ( this.i.equals("1") )
i = "3";
else
i = "4";
}
public static void main (String args []) {
T_7 aT_7 = new T_7("1");
aT_7.start();
aT_7.run();
synchronized ( aT_7 ) {
System.out.println("aT_7.i = " + aT_7.i );
System.out.println("aT_7.i = " + aT_7.i );
}
}
}
Source Code: Src/Question_Week_5/T_7.java
public class T_8 extends Thread {
static String i = null;
T_8(String i) {
this.i = i;
}
public void run () {
synchronized ( i ) {
if ( this.i.equals("1") )
i = "3";
else
i = "4";
}
}
public static void main (String args []) {
T_8 aT_8 = new T_8("1");
aT_8.start();
System.out.println("aT_8.i = " + aT_8.i );
System.out.println("aT_8.i = " + aT_8.i );
}
}
Source Code: Src/Question_Week_5/T_8.java
/*
* is this output 1 0 1 0 1 ...
* ...
* the only possible output?
*
* Falsch: es ist nichtgarantiert, in welcher die
* Threads eintreten.
*/
public class T extends Thread {
private String info;
static Object o = new Object();
public T (String info) {
this.info = info;
}
public void run () {
while ( true ) {
synchronized ( o ) {
System.out.println(info);
try {
o.notify();
sleep(100);
o.wait();
} catch ( Exception e ) { }
}
}
}
public static void main (String args []) {
( new T("0") ).start();
( new T("1") ).start();
}
}
Source Code: Src/Question_Week_5/T.java
public class H extends Thread {
String info = "";
public H (String info) {
this.info = info;
}
public synchronized void run () {
try {
while ( true ) {
System.out.println(info);
this.notify();
this.wait();
}
} catch ( Exception e ) {}
}
public static void main (String args []) {
new H("0").start();
new H("1").start();
}
}
Source Code: Src/Question_Week_5/H.java
/*
* is this output 1 0 1 0 1 ...
* ...
* the only possible output?
*
* Falsch: es ist nichtgarantiert, in welcher die
* Threads eintreten.
*/
public class X extends Thread {
private String info;
static Object o = new Object();
public X (String info) {
this.info = info;
}
public void run () {
while ( true ) {
synchronized ( o ) {
System.out.println(info);
try {
o.notify();
sleep(100);
o.wait();
} catch ( Exception e ) { }
}
}
}
public static void main (String args []) {
( new X("0") ).start();
( new X("1") ).start();
}
}
Source Code: Src/Question_Week_5/X.java
/*
* is this output 0 1 0 1 0 1 ...
* the only possible output?
*
*
*/
public class ZeroOneOrSo extends Thread {
private String info;
static Object o = new Object();
public ZeroOneOrSo (String info) {
this.info = info;
}
public void run () {
while ( true ) {
synchronized ( o ) {
o.notify();
System.out.println(info);
try {
sleep(300);
o.wait();
} catch ( Exception e ) { }
}
}
}
public static void main (String args []) {
new ZeroOneOrSo("0").start();
new ZeroOneOrSo("1").start();
}
}
Source Code: Src/Question_Week_5/ZeroOneOrSo.java
/*
* Should print out 0 1 0 1 0 1 ...
* Is this correct?
*
* nicht richtig,
* weil der Konstruktor fuer das Objekt mit der Id 0
* nicht zuende gehen muss bevor der 2. Konstruktor
* zuende geht.
*
*/
public class XXX extends Thread {
private String info;
static Object o = new Object();
public XXX (String info) {
this.info = info;
synchronized ( o ) {
if ( info.equals("0") )
( new XXX("1") ).start();
}
}
public void run () {
while ( true ) {
synchronized ( o ) {
System.out.println(info);
try {
o.notify();
sleep(100);
o.wait();
} catch ( Exception e ) { }
}
}
}
public static void main (String args []) {
new XXX("0").start();
}
}
Source Code: Src/Question_Week_5/XXX.java
Resource 1 and and resource 2 must be used exclusively
Process 1 holds resource 1 and is requestion resource 2
Process 2 holds resource 2 and is requestion resource 1
Have a situation in which there are K processes holding units of K resources
tape,
disk,
printer,
disk,
printer
import java.util.*;
public class DeadLock extends Thread {
private static String info;
public DeadLock (String info) {
this.info = info;
}
private void inProtected_1 () {
System.out.println(info + " tries to enter .... ");
synchronized ( info ) {
System.out.println(info + " is in protected_1()");
inProtected_2();
System.out.println(info + ": exit inProtected_1");
}
}
private void inProtected_2 () {
System.out.println(info + " tries to enter .... ");
synchronized ( info ) {
System.out.println(info + " is in protected_2()");
inProtected_1();
System.out.println(info + ": exit inProtected_2");
}
}
public void run () {
if ( info.equals("first") )
inProtected_1();
else
inProtected_2();
}
public static void main (String args []) {
new DeadLock("second").start();
new DeadLock("first").start();
}
}
Source Code: Src/11/DeadLock.java
import java.util.*;
public class DeadLock_2 extends Thread {
private String info;
private static Object o = new Object();
public DeadLock_2 (String info) {
this.info = info;
}
private void inProtected_1 () {
System.out.println(info + " tries to enter 1 .... ");
synchronized ( o ) {
System.out.println(info + " is in protected_1()");
inProtected_2();
System.out.println(info + ": exit inProtected_1");
}
}
private void inProtected_2 () {
System.out.println(info + " tries to enter 2 .... ");
synchronized ( o ) {
System.out.println(info + " is in protected_2()");
inProtected_1();
System.out.println(info + ": exit inProtected_2");
}
}
public void run () {
if ( info.equals("first") )
inProtected_1();
else
inProtected_2();
}
public static void main (String args []) {
new DeadLock_2("second").start();
try {
sleep(1000);
} catch ( Exception e ) {}
new DeadLock_2("first").start();
}
}
Source Code: Src/11/DeadLock_2.java
import java.util.*;
public class DeadLock_3 extends Thread {
private String info;
private static Object o_1 = new Object();
private static Object o_2 = new Object();
public DeadLock_3 (String info) {
this.info = info;
}
private void inProtected_1 () {
System.out.println(info + " tries to enter 1 .... ");
synchronized ( o_1 ) {
System.out.println(info + " is in protected_1()");
try {
sleep(1000);
} catch ( Exception e ) {}
inProtected_2();
System.out.println(info + ": exit inProtected_1");
}
}
private void inProtected_2 () {
System.out.println(info + " tries to enter 2 .... ");
synchronized ( o_2 ) {
System.out.println(info + " is in protected_2()");
try {
sleep(1000);
} catch ( Exception e ) {}
inProtected_1();
System.out.println(info + ": exit inProtected_2");
}
}
public void run () {
if ( info.equals("first") )
inProtected_1();
else
inProtected_2();
}
public static void main (String args []) {
new DeadLock_3("second").start();
new DeadLock_3("first").start();
}
}
Source Code: Src/11/DeadLock_3.java
The dining philosophers are often used to illustrate various problems that can occur when many synchronized threads are competing for limited resources.
import java.util.Random;
import java.util.Vector;
/** A class implementing the Dining Philosphers */
public class Philosopher extends Thread {
protected static Random random = new Random(); // randomize
protected int me; // number for trace
protected Integer left, right; // my chopsticks
public Philosopher (int me, Integer left, Integer right) {
this.me = me; this.left = left; this.right = right;
}
/** philosopher's body: think and eat 5 times */
public void run () {
for (int n = 1; n <= 5; ++ n) {
System.out.println(me+" thinks");
try {
Thread.sleep((long)(random.nextFloat()*1000));
} catch(Exception e) {
e.printStackTrace();
}
System.out.println(me+" is trying to eat");
synchronized ( left ) {
synchronized ( right ) {
System.out.println("\t" + me+" eats");
try {
Thread.sleep((long)(random.nextFloat()*1000));
} catch(Exception e) {
e.printStackTrace();
}
}
}
System.out.println("\t" + me+" leaves");
}
}
/** sets up for 5 philosophers */
public static void main (String args []) {
Integer f[] = new Integer[5];
for (int n = 0; n < 5; ++ n)
f[n] = new Integer(n);
Philosopher p[] = new Philosopher[5];
p[0] = new Philosopher(0, f[4], f[0]); // backwards
for (int n = 1; n < 5; ++ n)
p[n] = new Philosopher(n, f[n-1], f[n]);
for (int n = 0; n < 5; ++ n) p[n].start();
}
}
Source Code: Src/11/Philosopher.java
What is wrong with this solution?
1965, suggested Edsger. W. Dijkstra to using an integer variable to count the number of wakeups: Semaphores (semaphore is a greek word, it stands for signal). A synchronization variable that take a positive integer variable. A semaphore has two operations:
The P(S) operation on Semaphore S is:
If S > 0 then
S := S - 1
else
(Wait on S)
The V(S) operation on Semaphore S is:
If (One or more processes are waiting on S) then
(Let one of the processes proceed)
else
S := S + 1
It is assumed that P() and V() are indivisible.
If a thread tries to make a semaphore value to become negative, the thread is blocked until another thread makes the semaphore value positive.
public class Semaphore {
protected int n;
public Semaphore (int n) {
this.n = n;
}
public synchronized void P () {
if (n <= 0) {
try {
wait(); // see in object
} catch(Exception e) {
e.printStackTrace();
}
}
-- n;
}
public synchronized void V () {
if (++ n > 0)
notify(); // see in object
}
}
Source Code: Src/11/Semaphore.java
A thread blocks by calling wait(). Notification happens through notify() which, however, only releases one waiting thread from being blocked.
public class S extends Thread {
protected int n;
public S (int n) {
this.n = n;
}
public synchronized void P () {
if (n <= 0) {
try {
wait(); // see in object
} catch(Exception e) {
e.printStackTrace();
}
}
-- n;
}
public synchronized void V () {
if (++ n > 0)
notify(); // see in object
}
public void run() {
for ( int i = n; i >= 0; i -- ) {
System.out.println("i = " + i);
System.out.println("before P ");
P();
System.out.println("after P ");
}
}
static public void main(String args[] ) {
S aS1 = new S(3);
aS1.start();
try {
System.out.println("\tsleeping ...");
sleep(1000);
System.out.println("\tbefore V ");
aS1.V();
System.out.println("\tafter V ");
}
catch ( InterruptedException e ) {
System.err.println("\tInterrupted!");
}
}
}
Source Code: Src/11/S.java
i = 3
before P
after P
i = 2
before P
after P
i = 1
before P
after P
i = 0
before P
sleeping ...
before V
after P
after V
Two processes share a common fixed size buffer. One of them, the producer, puts information into the buffer and the consumer takes it out.
Trouble arises when the producer wants to put a new item in the buffer, but it is already full. Similarily, if the consumer wants to remove an item from the buffer when the buffer is empty.
We will use three semaphores to solve this problem.
no process is in its critical region.
What do you think about:
public class Consumer extends Thread {
final int N = 100;
Semaphore mutex = new Semaphore(1); // access the buffer semaphore
Semaphore empty = new Semaphore(N); // number of emtpy slots
Semaphore full = new Semaphore(0); // number of used slots
void insertItem(int i) { }
void consumeItem(int i) { }
void workWithIt(int i) { }
void producer()
{
int item;
while ( true ) {
item = (int)Math.random();
empty.P(); // decrement count of full slots
mutex.P(); // enter critical region
insertItem(item);
mutex.V(); // leave critical region
full.V(); // increment count of full slots
}
}
void consumer()
{
int item = 3;
while ( true ) {
full.P(); // decrement count of full slots
mutex.P(); // enter critical region
consumeItem(item); // take it
mutex.V(); // enter critical region
empty.V(); // increment count of full slots
workWithIt(item);
}
}
}
Source Code: Src/11/Consumer.java
What do you think about:
public class Consumer_2 extends Thread {
final int N = 100;
Semaphore mutex = new Semaphore(1); // access the buffer semaphore
Semaphore empty = new Semaphore(N); // number of emtpy slots
Semaphore full = new Semaphore(0); // number of used slots
void insertItem(int i) { }
void consumeItem(int i) { }
void workWithIt(int i) { }
void producer()
{
int item;
while ( true ) {
item = (int)Math.random();
mutex.P(); // enter critical region
empty.P(); // decrement count of full slots
insertItem(item);
mutex.V(); // leave critical region
full.V(); // increment count of full slots
}
}
void consumer()
{
int item = 3;
while ( true ) {
full.P(); // decrement count of full slots
mutex.P(); // enter critical region
consumeItem(item); // take it
mutex.V(); // enter critical region
empty.V(); // increment count of full slots
workWithIt(item);
}
}
}
Source Code: Src/11/Consumer_2.java
SORRY, it's only for me.
deadlock
What is going on here?
public class T_1 extends Thread {
private static synchronized void inProtected () {
System.err.println("--> ");
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("<-- ");
}
public void run () {
inProtected();
}
public static void main (String args []) {
new T_1().start();
new T_1().start();
new T_1().start();
}
}
Source Code: Src/11q/T_1.java
--> <-- --> <-- --> <--
public class T_2 extends Thread {
private String info;
public T_2 (String info) {
this.info = new String(info);
}
private void inProtected () {
synchronized ( info ) {
System.err.println("--> " + info);
try {
sleep(1000);
} catch ( Exception e ) {
e.printStackTrace();
}
System.err.println("<-- " + info);
}
}
public void run () {
inProtected();
}
public static void main (String args []) {
String a = "hello";
new T_2(a).start();
new T_2(a).start();
}
}
Source Code: Src/11q/T_2.java
--> hello --> hello <-- hello <-- hello
import java.util.Vector;
public class T_3 extends Thread {
static Vector aVector = new Vector();
private int info;
public T_3 (int info) {
this.info = info;
}
public synchronized void run () {
System.err.println("--> " + info);
try {
sleep(1000);
} catch ( Exception e ) {
e.printStackTrace();
}
System.err.println("<-- " + info);
}
public static void main (String args []) {
for ( int i = 1; i < 100; i ++ )
new T_3(i).start();
}
}
Source Code: Src/11q/T_3.java
--> 1 --> 2 --> 3 --> 4 --> 5 ... <-- 94 <-- 95 <-- 96 <-- 97 <-- 98 <-- 99
import java.util.*;
public class T_4 extends Thread {
static Object o = new Object();
public void run () {
synchronized ( o ) {
System.err.println("--->");
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("<---" );
}
}
public static void main (String args []) {
new T_4().start();
new T_4().start();
new T_4().start();
}
}
Source Code: Src/11q/T_4.java
---> <--- ---> <--- ---> <---
import java.util.*;
public class T_5 extends Thread {
static Object o = new Object();
static int counter = 0;
public void run () {
if ( ++counter == 1 )
o = new Object();
synchronized ( o ) {
System.err.println("--->" );
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("<---" );
}
}
public static void main (String args []) {
new T_5().start();
new T_5().start();
new T_5().start();
}
}
Source Code: Src/11q/T_5.java
---> <--- ---> <--- ---> <---
import java.util.*;
public class T_6 extends Thread {
static Object o = new Object();
static int counter = 0;
public void run () {
if ( counter++ == 1 )
o = new Object();
synchronized ( o ) {
System.err.println("--->" );
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println("<---" );
}
}
public static void main (String args []) {
new T_6().start();
new T_6().start();
new T_6().start();
}
}
Source Code: Src/11q/T_6.java
---> ---> <--- <--- ---> <---
import java.util.Vector;
public class T_1 extends Thread {
private String info;
Vector aVector;
Vector bVector;
public T_1 (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
public void run() {
synchronized ( aVector ) {
if ( info.equals("last") ) {
aVector.notifyAll();
} else {
System.out.println(info + " is waiting");
try {
aVector.wait();
} catch ( Exception e ) {
System.out.println(info +
": InterruptedException");
}
System.out.println(info + " is awake!");
}
}
}
public static void main (String args []) {
Vector aVector = new Vector();
Vector bVector = new Vector();
new T_1("first", aVector).start();
new T_1("second", bVector).start();
new T_1("last", bVector).start();
}
}
import java.util.*;
public class M extends Thread {
private String info;
private Vector aVector;
public M (String info) {
this.info = info;
}
private synchronized void inProtected () {
System.err.println(info + ": is in protected()");
try {
sleep(1000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println(info + ": exit run");
}
public void run () {
inProtected();
}
public static void main (String args []) {
Vector aVector = new Vector();
M aT4_0 = new M("first");
M at5_0 = new M("second");
aT4_0.start();
at5_0.start();
aT4_0.inProtected();
at5_0.inProtected();
}
}
Source Code: Src/StudentT_Q/M.java
/*
Q2. If the object is synchronized in the main method, what is the significance of doing so? In the code below,in the main method, the object is synchronized after the run() method is executed. What is the significance of doing this?
Q3.In what scenario will a running thread go to a ready state?
Q4.In the slide numbered 12.8, it says Interface methods cannot be sychronized.We have not understood that part.
*/
public class T_7 extends Thread {
static String i = null;
T_7(String i) {
this.i = i;
}
public void run () {
if ( this.i.equals("1") )
i = "3";
else
i = "4";
}
public static void main (String args []) {
T_7 aT_7 = new T_7("1");
aT_7.start();
aT_7.run();
synchronized ( aT_7 ) { //We did not understand this part.
System.out.println("aT_7.i = " + aT_7.i );
System.out.println("aT_7.i = " + aT_7.i );
}
}
}
Source Code: Src/StudentT_Q/T_7.java
/*
Q2. If the object is synchronized in the main method, what is the significance of doing so? In the code below,in the main method, the object is synchronized after the run() method is executed. What is the significance of doing this?
Q3.In what scenario will a running thread go to a ready state?
Q4.In the slide numbered 12.8, it says Interface methods cannot be sychronized.We have not understood that part.
*/
public class T_8 extends Thread {
static String i = null;
T_7(String i) {
this.i = i;
}
public void run () {
if ( this.i.equals("1") )
i = "3";
else
i = "4";
}
public static void main (String args []) {
T_7 aT_7 = new T_7("1");
aT_7.start();
aT_7.run();
synchronized ( aT_7 ) { //We did not understand this part.
System.out.println("aT_7.i = " + aT_7.i );
System.out.println(aT_7.i = " + aT_7.i );
}
}
}
Source Code: Src/StudentT_Q/T_8.java
import java.util.*;
public class TestThread extends Thread {
private int number;
static Object o = new Object();
boolean firstThreadRunning = false;
public TestThread (int info) {
this.number = info;
}
public void run () {
while(true) {
synchronized(o) {
o.notify();
System.out.println(number);
if(! firstThreadRunning) {
try {
firstThreadRunning = true;
new TestThread(2).start();
sleep(100);
o.wait();
} catch (Exception e) {}
}
else {
new TestThread(1).start();
firstThreadRunning = false;
}
}
}
}
public static void main (String args []) {
new TestThread(1).start();
}
}
Source Code: Src/StudentT_Q/TestThread.java
import java.util.*;
public class TestThread_2 extends Thread {
private int number;
static Object o = new Object();
static boolean firstThreadRunning = false;
public TestThread_2 (int info) {
this.number = info;
}
public void run () {
while(true) {
synchronized(o) {
o.notify();
System.out.println(number);
if(! firstThreadRunning) {
try {
firstThreadRunning = true;
new TestThread_2(2).start();
sleep(100);
} catch (Exception e) {}
}
else {
new TestThread_2(1).start();
firstThreadRunning = false;
}
try {
o.wait();
} catch (Exception e) {}
}
}
}
public static void main (String args []) {
new TestThread_2(1).start();
}
}
Source Code: Src/StudentT_Q/TestThread_2.java
import java.util.*;
public class TestThread_3 extends Thread {
private int number;
static Object o = new Object();
static boolean firstThreadRunning = false;
static int justPrinted = 2;
public TestThread_3 (int info) {
this.number = info;
}
public void run () {
while(true) {
synchronized(o) {
o.notify();
if ( justPrinted == number ) {
System.out.println(justPrinted + "/" + number );
System.exit(2);
} else
justPrinted = number;
System.out.println(number);
if(! firstThreadRunning) {
try {
firstThreadRunning = true;
new TestThread_3(2).start();
sleep(100);
} catch (Exception e) {}
}
try {
o.wait();
} catch (Exception e) {}
}
}
}
public static void main (String args []) {
new TestThread_3(1).start();
}
}
Source Code: Src/StudentT_Q/TestThread_3.java
/*
* This program tries to synchronize block on object
* with info
*
*
* Although I am able to synchronize block with
* synchronized (aVector) why am I not be able
* synchronize with private String info; ??
*/
import java.util.*;
public class Thread_5 extends Thread {
private String info;
private Vector aVector;
public Thread_5 (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
public void inProtected () {
synchronized (info ) { // synchronized (aVector ) works ??
System.err.println(info + ": is in protected()");
try {
if ( info.equals("second") )
sleep(1000);
else
sleep(3000);
}
catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println(info + ": exit run");
}
}
public void run () {
inProtected();
}
public static void main (String args []) {
Vector aVector = new Vector();
Thread_5 aT5_0 = new Thread_5("first", aVector);
Thread_5 aT5_1 = new Thread_5("second", aVector);
aT5_0.start();
aT5_1.start();
}
}
Source Code: Src/StudentT_Q/Thread_5.java
/*
Q2. If the object is synchronized in the main method, what is the significance of doing so? In the code below,in the main method, the object is synchronized after the run() method is executed. What is the significance of doing this?
Q3.In what scenario will a running thread go to a ready state?
Q4.In the slide numbered 12.8, it says Interface methods cannot be sychronized.We have not understood that part.
*/
public class T_8 extends Thread {
static String i = null;
T_7(String i) {
this.i = i;
}
public void run () {
if ( this.i.equals("1") )
i = "3";
else
i = "4";
}
public static void main (String args []) {
T_7 aT_7 = new T_7("1");
aT_7.start();
aT_7.run();
synchronized ( aT_7 ) { //We did not understand this part.
System.out.println("aT_7.i = " + aT_7.i );
System.out.println("aT_7.i = " + aT_7.i );
}
}
}
Source Code: Src/StudentT_Q/Thread_6.java
/*
* Q1. In this program, when will the run method be called? How is the control transferred in the program?
*/
public class XXX extends Thread {
private String info;
static Object o = new Object();
public XXX (String info) {
this.info = info;
synchronized ( o ) {
if ( info.equals("0") )
( new XXX("1") ).start();
}
}
public void run () {
int id = 0;
while ( true ) {
synchronized ( o ) {
System.out.println(info);
try {
o.notify();
sleep(100);
o.wait();
} catch ( Exception e ) { }
}
}
}
public static void main (String args []) {
new XXX("0").start();
}
}
Source Code: Src/StudentT_Q/XXX.java
public class T_1 extends Thread
{
private String info;
public T_1(String info) {
this.info= info;
}
private void inprotected() {
synchronized(info) {
System.err.println("----->"+this.info);
try
{
sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
System.err.println("<-----"+this.info);
}
}
public void run() {
inprotected();
}
public static void main(String args[]) {
String a ="1";
String b= "2";
new T_1(b).start();
new T_1(a).start();
}
}
Source Code: Src/StudentT_Q/T_1.java
/*
* Should print out 0 1 0 1 0 1 ...
*
*
*/
public class ZeroOne extends Thread {
private String info;
Object o = new Object();
static boolean oneIsRunning = false; // is static important?
// es wird nur ein
// Objekt erzeugt
public ZeroOne (String info) {
this.info = info;
}
public void run () {
while ( true ) {
synchronized ( o ) {
o.notify();
System.out.println(info);
try {
if ( ! oneIsRunning ) {
( new ZeroOne("1") ).start();
oneIsRunning = true;
}
sleep(300);
o.wait();
} catch ( Exception e ) { }
}
}
}
public static void main (String args []) {
new ZeroOne("0").start();
}
}
Source Code: Src/Question_Week_5/ZeroOne.java
|
|