Pract3

advertisement
Concurrent & Distributed Computing
PRACTICAL 3 – Java Threads
Question 1 – Introducing Java Threads
There are two different ways of creating a thread.
First way to create a thread
Create a new subclass of the Thread class and override the run method, for example:
class SimpleThread1 extends Thread
{
public void run()
{
for ( int count = 0; count < 4; count++)
System.out.println( "Message " + count + "From: " + getName() );
}
}
A SimpleThread1 object(i.e. parallel) can now be created and started running (using
parallel.start()) to run in parallel with the main method thread itself.
class TestThread1
{
public static void main( String[] args )
{
SimpleThread1 parallel = new SimpleThread1();
System.out.println( "Create the thread");
parallel.start();
System.out.println( "Started the thread" );
System.out.println( "End" );
}
}
(a) Create the SimpleThread1 class and use it in the TestThread1 class. Observe the output
and verify its correctness.
Second way to create a thread
The second way of creating threads is to implement the Runnable interface (provided by
Java) in a class and then an object of this class can be made into a thread (by passing it to
the constructor of the Thread class). The resulting thread can then be started and it’s run()
method will execute. For example:
class PossibleThread2 implements Runnable
{
public void run()
{
for ( int count = 0; count < 4; count++)
System.out.println( "Message " + count + " From: " + Thread.currentThread().getName() );
}
}
Now consider a main program that instantiates a Runnable object (i.e. notAThread) and
passes it as a parameter to the constructer of the Thread class. The thread object (i.e.
parallelThread) can now be started.
1
class TestThread2
{
public static void main( String[] args )
{
PossibleThread2 notAThread = new PossibleThread2();
Thread parallelThread = new Thread( notAThread );
System.out.println( "Create the thread");
parallelThread.start();
System.out.println( "Started the thread" );
System.out.println( "End" );
}
}
(b) Create the PossibleThread2 class and use it in the TestThread2 class. Observe the
output and verify its correctness.
Question 2 – Giving a thread a Name
When you create a thread you have the option of giving it a textual name, which is passed
as a parameter when you create it.
Example of Thread Use
Run the program RunThreads.java. This program creates two instances of the
ShowlineThread class.
/* RunThreads.java */
class RunThreads
{
public static void main(String args[])
{
Showline possibleThread = new Showline(); //create object that can become a thread
Thread t1 = new Thread ( possibleThread, "Kate" ); // call thread constructor to make thread
Thread t2 = new Thread ( possibleThread, "John" ); // call thread constructor to make thread
t1.start(); // start thread
t2.start(); // start thread
}
}
/* Showline.java */
public class Showline implements Runnable
{
public void run()
{
while (true)
System.out.println(Thread.currentThread().getName()); // gets current threads name and print it
}
(a) Verify that the output is as expected.
(b) Introduce two more threads called “Mary” and “Peter” and run them concurrently with the
existing threads.
2
Question 3 – Sleeping Threads
Now look at the three classes: RunIdlers.java, Idler.java, and CDS.java (below).
RunIdlers creates two Idler objects:
Idler lover = new Idler(8000);
Idler hater = new Idler(16000);
The numbers 8000 and 16000 are millisecond lengths (8 seconds, and 16 seconds).
Look at the constructor method for the Idler object. The millisecond lengths are copied to a
private variable, private_idle, inside the Idler object.
Consider the creation of the threads in main. These two lines kick-off the run() method in the
Idler objects.
new Thread(lover, "She loves me").start();
new Thread(hater, "No, she hates me").start();
The run() method contains an infinite loop. The thread prints out its name then sleeps for
the number of milliseconds prescribed by its private variable.
Finally, look at the idle() method in the class CDS.java. It causes the currently executing
thread to sleep for a certain number of milliseconds and prints out the name of the thread
before it sleeps and when it wakes up.
class RunIdlers
{
public static void main(String args[])
{
Idler lover = new Idler(8000);
Idler hater = new Idler(16000);
new Thread(lover, "She loves me").start();
new Thread(hater, "No, she hates me").start();
}
}
public class Idler implements Runnable
{
private int private_idle;
Idler (int idleTime) // constructer
{
private_idle = idleTime;
}
public void run()
{
while (true)
{
System.out.println(“Current Thread is:” + Thread.currentThread().getName());
CDS.idle (private_idle);
}
} // end run
} // end Idler
// CDS.java - Useful class for Concurrent and Distributed Systems
public class CDS
{
public static void idle (int millisecs)
{
Thread mainThread = Thread.currentThread();
System.out.println(mainThread.getName() + ": About to sleep");
try {
3
Thread.sleep(millisecs);
} catch (InterruptedException e) { }
System.out.println (mainThread.getName() + ": Woken up");
} // end idle
} // end CD
(a) Run the “RunIdlers” program and verify the output.
(b) Alter the run() methods so that the private variable is used to specify the maximum
length of time that the process sleeps (rather than the actual time) on each iteration of
the loop. That is let it sleep a random length of time up to the maximum. You can use
Math.random() to simulate random lengths of time.
(c) Put a loop in the main() method of RunIdlers which occasionally prints out a statement to
show that RunIdlers can execute concurrently with the two threads.
Question 4 – More Threads
The application below consists of classes ThreadDemo and MyThread.
Class ThreadDemo drives the application by creating a MyThread object and starting it. The
ThreadDemo class then prints the “squares times table” for the numbers 1..50.
In concurrent fashion MyThread overrides Thread's run() method to print (on the standard
output stream) a right-angle triangle composed of asterisk characters.
// ThreadDemo.java
class ThreadDemo
{
public static void main (String [] args)
{
MyThread mt = new MyThread ();
mt.start ();
for (int i = 0; i < 50; i++)
System.out.println ("i = " + i + ", i * i = " + i * i);
}
}
class MyThread extends Thread
{
public void run ()
{
for (int count = 1, row = 1; row < 20; row++, count++)
{
for (int i = 0; i < count; i++)
System.out.print ('*');
System.out.print ('\n');
}
}
}
(a) Run this program and verify the output.
(b) Incorporate delays to try and have the triangle printed before and then after the square.
4
Question 5 – Threads (Unpredictable output)
In the example below, we'll create and start two threads, each of which prints two lines to
System.out:
public class TwoThreads
{
public static class Thread1 extends Thread
{
public void run()
{
System.out.println("A");
System.out.println("B");
}
}
public static class Thread2 extends Thread
{
public void run()
{
System.out.println("1");
System.out.println("2")
}
}
public static void main(String[] args)
{
new Thread1().start();
new Thread2().start();
}
}
We have no idea in what order the lines will execute, except that "1" will be printed before "2"
and "A" before "B." The output could be any one of the following:
•12AB
•1A2B
•1AB2
•A12B
•A1B2
•AB12
(a) Verify that this is the case.
(b) Put in appropriate delays to ensure the letters are output before the numbers.
(c) Make both threads print their output forever and see the results.
Note. You will need to experiment with random delays at different points in the code to get the
output you require.
END
5
Download