Exercise 1 4 points modify the program ThreadJoin so that th
Exercise 1 (4 points): modify the program ThreadJoin so that the threads start and finish in the following sequence t2, t1, t4, t3, and t5 (i.e. t2 should start and finish before t1. T1 should start and finish before t4. Etc).
Exercise 2 (6 points): use the methods wait() and notify() to modify the program RestaurantSynchronized. Specifically Cook and Waiter should wait and notify each other any time they need to update OrderList. Should you also use the keyword synchronized along with wait() and notify() ? Provide your motivation to either use it or not.
Solution
package threadExamples;
import java.util.Vector;
public class RestaurantSinchronized {
static Cook c;
static Waiter w;
static OrdersList o;
public static void main( String args[] ){
RestaurantSinchronized restaurant = new RestaurantSinchronized();
// instantiating shared resource
RestaurantSinchronized.o = restaurant.new OrdersList();
RestaurantSinchronized.c = restaurant.new Cook( o );
c.start();
RestaurantSinchronized.w = restaurant.new Waiter( o );
w.start();
}
class OrdersList{
private Vector<Order> orders = new Vector<Order>();
private final Object lock = new Object();
void addOrder( Order order ){
synchronized(lock){
orders.add(order);
}
}
void updateOrder( int position, Order order ){
synchronized(lock){
orders.setElementAt(order, position);
}
}
Order getOrder( int position ){
synchronized(lock){
return orders.remove( position );
}
}
Vector<Order> getOrders(){
return orders;
}
}
class Order{
String item;
boolean isCooking = false;
boolean isReady = false;
public Order( String item ){
this.item = item;
}
}
class Cook extends Thread{
private OrdersList gs;
public Cook( OrdersList gs ){
this.gs = gs;
}
public void run()
{
synchronized(this){
Vector<Order> orders = new Vector<Order>();
Order order;
boolean ordersCompleted = false;
while(true){
orders = gs.getOrders();
if( orders.size() == 0 ){
try {
System.out.println( \"Cook (Thread: \" + getId() + \") is waiting for orders to come in\" );
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if( ordersCompleted ){
try {
System.out.println( \"Cook (Thread: \" + getId() + \") has cooked all the orders\" );
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ordersCompleted = false;
}else{
for(int j=0; j<orders.size(); j++){
if( orders.size()-1 == j ){
ordersCompleted = true;
break;
}
if( orders.elementAt(j).isCooking ){
order = orders.elementAt(j);
order.isReady = true;
System.out.println( \"Cook (Thread: \" + getId() + \") has new order ready \" + order.item );
gs.updateOrder(j, order);
}else{
order = orders.elementAt(j);
order.isCooking = true;
System.out.println( \"Cook (Thread: \" + getId() + \") is now working on \" + order.item );
gs.updateOrder(j, order);
break;
}
}
}
}
}
}
}
class Waiter extends Thread{
private OrdersList gs;
private String meals[] = {\"pizza\", \"ice cream\", \"pasta\", \"corn\", \"hotdog\", \"lasagna\", \"steak\", \"french toast\", \"pancakes\", \"salad\"};
public Waiter( OrdersList gs ){
this.gs = gs;
}
public void run(){
int i;
Vector<Order> orders;
while(true){
i = (int) (Math.random() * 10);
Order order = new Order( meals[i] );
System.out.println(\"Waiter (Thread: \" + getId() + \") is adding a new order: \" + meals[i] );
gs.addOrder( order );
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
orders = gs.getOrders();
for(int j=0; j<orders.size(); j++){
if( orders.elementAt(j).isReady){
order = gs.getOrder(j);
System.out.println( \"Waiter (Thread: \" + getId() + \") is going to deliver \" + order.item );
}
}
}
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package threadExamples;
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(\"Thread started: \"+ Thread.currentThread().getName());
int waitTime = (int) (10000 * Math.random());
try {
Thread.sleep( waitTime );
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(\"Thread ended: \"+ Thread.currentThread().getName());
}
}
public class ThreadJoin {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable(), \"t1\");
Thread t2 = new Thread(new MyRunnable(), \"t2\");
Thread t3 = new Thread(new MyRunnable(), \"t3\");
Thread t4 = new Thread(new MyRunnable(), \"t4\");
Thread t5 = new Thread(new MyRunnable(), \"t5\");
//t1.start();
//t2.start();
//t3.start();
//t4.start();
//t5.start();
// join() allows one thread to pause for the completion of another thread
try {
t2.start();
t2.join();
System.out.println(\"Thread \" + t2.getName() + \" has finished.\");
t1.start();
t1.join();
System.out.println(\"Thread \" + t1.getName() + \" has finished.\");
t4.start();
t4.join();
System.out.println(\"Thread \" + t4.getName() + \" has finished.\");
t3.start();
t3.join();
System.out.println(\"Thread \" + t3.getName() + \" has finished.\");
t5.start();
t5.join();
System.out.println(\"Thread \" + t5.getName() + \" has finished.\");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(\"All threads completed thier execution\");
}
}
please check its working wonder




