Computer
Science
School
Dr. Eliahu Khalastchi
2017
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
A quick recap
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Process 5
Process 6
Operating System Processes and Threads…
Process 7 Context Switch
Process 8
Process 1 Process 2 Process 3 Process 4
thread1 thread2 thread1
thread2
VM
thread3
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
What is more useful to us?
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Processes vs. Threads
I want more CPU time and Memory from the system
Processes
I should write ____________
I want to gracefully degrade upon a crash
I should write ____________
Processes
I want to easily share memory
I should write ____________
Threads
I want to switch quickly between tasks
I should write ____________
Threads
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Writing in threads, is it faster?
Yes!
A typical code usually involves (a lot of) I\O requests
Whenever the thread waits for I\O - it is blocked
And another thread is executed in the meanwhile… saving execution time
Blocked
Scheduler choice
Ready Queue
End of Time slice Running
C B A
Thumb rule 1: A code that requests a lot of I\O should be executed as a thread!
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
In Java
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
What is the problem here?
public class CLI {
public void start() throws IOException{
public class MyTask {
long x; MyTask t=new MyTask();
volatile boolean stop;
[Link]("1. start task");
public MyTask() { [Link]("2. get X");
stop=false; [Link]("3. stop task");
x=0; [Link]("4. exit");
} BufferedReader in=new BufferedReader(new
public void doTask(){ InputStreamReader([Link]));
while(!stop){ int input=0;
x++; while(input!=4){
} input=[Link]([Link]());
} switch(input){
public void stopTask(){ case 1: [Link]();break; We are stuck here forever!!!
stop=true; case 2: [Link]([Link]());break;
} case 3: [Link]();break;
long getX(){ return x;} }
} }
}
}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Thread & Runnable
<<Runnable>>
void run()
Thread
Runnable r;
void run() {
[Link]();
}
void start() Tells the JVM to execute run() in a thread
… i.e., run() enters the Ready Queue
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Option 1: extending Thread
1. Extended the Thread class
2. Override the run() method
Thread
3. Call start to execute in parallel
run()
start()
// in the CLI class
MyTask t=new MyTask();
int input=0;
MyTask while(input!=4){
input=[Link]([Link]());
run(){ doTask(); } switch(input){
case 1: [Link]();break; // now it’s asynchronous execution
case 2: [Link]([Link]());break;
case 3: [Link]();break;
}
}
But sometimes our class is not a type of Thread or it already extends something else
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Option 2: implementing Runnable
1. Implement the Runnable interface
2. Create an instance of Thread
Thread <<Runnable>> 3. Inject the Runnable
start() run() 4. Call start
// in the CLI class
MyTask MyTask task=new MyTask(); // it’s a type of Runnable
Thread t=new Thread(task);
//...
run(){ doTask(); }
case 1: [Link]();break; // now it’s asynchronous execution
This is a typical strategy pattern, but what if we don’t want to (or can’t) change MyTask?
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Option 3: using object adapters!
Thread <<Runnable>> Thread t=new Thread(new TaskRunnable(new MyTask()));
start() run() [Link]();
TaskRunnable
<<Task>>
Task t; doTask()
run(){ [Link](); }
MyTask
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Option 4: owning a thread
MyTask can own a thread instead of being ran as a thread
Use it if we always need the task to run in parallel
// in MyTask class we create a thread
public void doTask(){ // using anonymous class
new Thread(new Runnable() {
@Override
public void run() {
while(!stop){
x++;
}
}
}).start();
}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Option 4: owning a thread
MyTask can own a thread instead of being ran as a thread
Use it if we always need the task to run in parallel
// in MyTask class we create a thread
public void doTask(){// using lambda!
new Thread(
()-> {
while(!stop){
x++;
}
}
).start();
}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Best Choice!
Let’s decuple the task and user interface
The UI should be executed as a Thread due to its I/O
The Task is a Task, someone else can run it as a Thread
public class CLI extends Thread{ // run the task in parallel
Task task; private void runTaskInThread(){
public CLI(Task task) { new Thread(()->[Link]()).start();
[Link]=task; }
}
public void run(){ // the main
... CLI ui=new CLI(new MyTask());
case 1: runTaskInThread();break; [Link]();
... // the main thread is now dead.
} // the ui thread continues...
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Sleep, Wait, Join
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread class
The thread class has many control methods
We can make a thread fall asleep
We can weak it up with an interrupt
We can cause it to wait and notify it when to continue
We can wait for it to end
We can ask if it is still alive
Etc.
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread Life Cycle
Thread tA
while((line = [Link]())!=null){
String sp[]=[Link](“,”);
for(String s : sp)
[Link](s);
}
[Link]();
Thread tB Scheduler choice
obj.foo1(); Ready Queue
… Born C B A Running
[Link](1000);
…
obj.foo2();
[Link]();
Thread tC
obj.foo1();
…
[Link]();
…
obj.foo2();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread Life Cycle
Thread tA
while((line = [Link]())!=null){
String sp[]=[Link](“,”); Blocked
for(String s : sp)
[Link](s);
}
[Link]();
Thread tB Scheduler choice
obj.foo1(); Ready Queue
… Born C B Running A
[Link](1000);
…
obj.foo2();
[Link]();
Thread tC
obj.foo1();
…
[Link]();
…
obj.foo2();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread Life Cycle
Thread tA
while((line = [Link]())!=null){
String sp[]=[Link](“,”); Blocked
for(String s : sp)
[Link](s);
A
}
[Link]();
Thread tB Scheduler choice
obj.foo1(); Ready Queue
End of Time slice Running B
… Born C
[Link](1000);
…
obj.foo2();
[Link]();
Thread tC
obj.foo1();
…
[Link]();
…
obj.foo2();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread Life Cycle
Thread tA
while((line = [Link]())!=null){
String sp[]=[Link](“,”); Blocked
for(String s : sp)
[Link](s);
A
}
[Link]();
Thread tB Scheduler choice
obj.foo1(); Ready Queue
End of Time slice Running B
… Born C
[Link](1000);
…
obj.foo2();
[Link]();
Thread tC Sleep
obj.foo1();
…
[Link]();
…
obj.foo2();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread Life Cycle
Thread tA
while((line = [Link]())!=null){
String sp[]=[Link](“,”); Blocked
for(String s : sp)
[Link](s);
}
[Link]();
Thread tB Scheduler choice
obj.foo1(); Ready Queue
End of Time slice Running C
… Born A
[Link](1000);
…
obj.foo2(); [Link](x)
[Link]();
Thread tC Sleep
[Link]()
obj.foo1(); B
…
[Link]();
…
Wait
obj.foo2();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread Life Cycle
Thread tA
while((line = [Link]())!=null){
String sp[]=[Link](“,”); Blocked
for(String s : sp)
[Link](s);
}
[Link]();
Thread tB Scheduler choice
obj.foo1(); Ready Queue
End of Time slice Running
… Born B Dead
[Link](1000); A
…
obj.foo2(); [Link](x)
[Link]();
Thread tC Sleep
obj.foo1(); [Link]()
…
[Link]();
…
Wait
obj.foo2(); C
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
The Thread Life Cycle
Thread tA
while((line = [Link]())!=null){
String sp[]=[Link](“,”); Blocked
for(String s : sp)
[Link](s);
}
[Link]();
Thread tB Scheduler choice
obj.foo1(); Ready Queue
End of Time slice Running
… Born C Dead
[Link](1000); B
… A
obj.foo2(); [Link](x)
[Link]();
Thread tC Sleep
obj.foo1(); [Link]()
…
[Link]();
…
Wait
obj.foo2();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
What is preferable?
// wait for threat t to finish // wait for threat t to finish
while([Link]()); while([Link]()){
// continue [Link](3*1000);
This is busy waiting!!! } // continue
This is not accurate enough
// wait for thread t to finish
[Link](5*1000); // wait for threat t to finish
// continue [Link]();
This is guessing! // continue
No busy waiting nor guessing
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
can and be at the same spot?
public class PacmanGame { public class Ghost1 extends Thread{
private PacmanGame pg;
int maze[][]={/*...*/}; private int x,y;
public Ghost1(PacmanGame pg) {
public void moveGhost1(int x,int y){ [Link]=pg;
if(maze[y][x]==0)// clear? }
maze[y][x]=1; public void run(){
} // calculate strategy...
//...
public void moveGhost2(int x,int y){ pg.moveGhost1(x, y);
if(maze[y][x]==0)// clear? } // main
maze[y][x]=2; } PacmanGame pg=new PacmanGame();
} Ghost1 g1=new Ghost1(pg);
Ghost2 g2=new Ghost2(pg);
} [Link]();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 © [Link]();
Computer
Science
School
Sure they can be at the same spot!
public class PacmanGame {
int maze[][]={/*...*/};
• Both threads can cross the IF sentence in the same time
public void moveGhost1(int x,int y){ • Before anyone of them sets a value to maze[y][x]
if(maze[y][x]==0)// clear? :G1 • One of the values is overwritten and lost…
maze[y][x]=1;
}
maze[y][x]== 120
public void moveGhost2(int x,int y){
if(maze[y][x]==0)// clear? :G2
maze[y][x]=2;
}
}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Sure they can be at the same spot!
public class PacmanGame {
int maze[][]={/*...*/};
• Both threads can cross the IF sentence in the same time
public void moveGhost1(int x,int y){ • Before anyone of them sets a value to maze[y][x]
if(maze[y][x]==0)// clear? • One of the values is overwritten and lost…
maze[y][x]=1;
}
public void moveGhost2(int x,int y){ • We can solve this problem using synchronize!
if(maze[y][x]==0)// clear?
maze[y][x]=2; • In the next lesson we’ll learn about
} • Problems with synchronize
• Advanced tools instead
}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Synchronized methods
public class PacmanGame {
While a thread is executing a synchronized
int maze[][]={/*...*/}; method of an object o, all other threads that
try to access any other synchronized methods
synchronized public void moveGhost1(int x,int y){ of o are blocked until the thread has finished
if(maze[y][x]==0)// clear? executing the method.
maze[y][x]=1;
} They can execute other methods of o.
They can execute synchronized methods of
synchronized public void moveGhost2(int x,int y){ other objects.
if(maze[y][x]==0)// clear? They cannot execute synchronized methods of o.
maze[y][x]=2;
}
}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
MyObject o
Thread t1: o.m1(); Locked by t1
Thread t2: o.m1(); public synchronized m1() {…}
public synchronized m2() {…}
Thread t2: o.m2();
public m3() {…}
Thread t2: o.m3();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
MyObject o
Locked by t2
Thread t2: o.m1(); public synchronized m1() {…}
public synchronized m2() {…}
Thread t2: o.m2();
public m3() {…}
Thread t2: o.m3();
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
MyObject o
Thread t1: o.m1(); Locked by t1
public synchronized m1() {…}
public synchronized m2() {…}
public m3() {…}
Thread t2: o2.m1(); MyObject o2
Locked by t2
public synchronized m1() {…}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©
Computer
Science
School
Other ways to use synchronized
A synchronized block: Static methods can also be
synchronized
public void m(){ Every class has an object:
// not synced… Class class;
synchronized(myObject) { As every other object it has a lock
// synced code
}
// not synced…
}
Advanced Software Development 2, Dr. Eliahu Khalastchi, 2017 ©