Next page | Contents page |

Threads

So far the JVM has started one execution thread when we have run an application. It has always started in main().

It is possible to start other threads, to run in parallel. This can be done in 2 ways:

  1. extend class java.lang.Thread and override its run() method.
  2. implement the interface java.lang.Runnable, which has one method: run()

Either way, your version of public void run() can do anything it likes!

When we say the threads run in parallel, what really happens depends on how many processors there are in your system and whether the JVM can use them all. Pseudo-parallel execution is achieved on a single processor by a scheduler in the JVM swapping threads, giving each a slice of time.

Threads are lightweight processes, faster to switch between than complete operating system processes.

The fun starts when you have more than one thread trying to work with the same variables in your application. It can be managed but you must be careful. Some methods in the standard API are thread-safe in that respect. Others are not but the documentation should make that clear.

Programming concurrent threads is not trivial. It is easy to make programs hang because all threads are waiting for the same resource. Classic situations of this this kind are known as "deadlock" and "the deadly embrace". A simple strategy that works, if you can stick to it, is to ensure that all threads acquire the resources they need in the same order.

You may well want to find another course or some books to master all the subtleties of concurrent programming. Be warned!

Method 1: subclass Thread

public class ThreadDemo1 extends Thread
{
	String msg;   
	int count, dt;

	public ThreadDemo1 (String msg, int count, int dt)
	{
		this.msg = msg;  this.count = count;   this.dt = dt;
		setName (msg + " runner"); 
	}

	@Override
	public void run ()
	{ 
		while (count-- > 0)
		{ 
			System.out.println (msg);
		
			try 
			{
				Thread.sleep (dt); // ms
			}
			catch (InterruptedException ex) { return; }
		}
		
		System.out.println (msg + " done");
	} // run

	/** Demonstrate 3 threads running */
	public static void main (String... args)
	{
		new ThreadDemo1 ("Thread 1", 7, 100).start (); // NB: NOT run ()
		new ThreadDemo1 ("Thread 2", 5, 150).start ();
		new ThreadDemo1 ("Thread 3", 10, 75).start ();
	} // main
	
}// ThreadDemo1

Method 2: implement Runnable

public class ThreadDemo2 implements Runnable
{
	String msg;  
	int count, dt;  
	Thread th;

	public ThreadDemo2 (String msg, int count, int dt)
	{ 
		this.msg = msg;  this.count = count;  this.dt = dt;
		th = new Thread (this);  
		th.start ();
	}

	/** Defined exactly as before */
	@Override
	public void run ()
	{ 
		while (count-- > 0)
		{ 
			System.out.println (msg);
		
			try 
			{
				Thread.sleep (dt); // ms
			}
			catch (InterruptedException ex) { return; }
		}
		
		System.out.println (msg + " done");
	} // run

	/** Demonstrate 3 threads running */
	public static void main (String [ ] args)
	{
		new ThreadDemo2 ("Thread 1", 7, 100);
		new ThreadDemo2 ("Thread 2", 5, 150);
		new ThreadDemo2 ("Thread 3", 10, 75);
	} // main

} // ThreadDemo2

NB: You may need to replace some HTML characters in the cut and pasted text for the 2 classes: &lt; should be <, &gt; should be >, &quot; should be ".

Next page | Contents page |