|
|
Title |
Using threads
|
Summary |
This note shows how to create and use threads for simple processing. It also touches on synchronisation. |
Contributor |
John McTainsh
|
Published |
28-Oct-2000 |
Last updated |
28-Oct-2000 |
|
|
Description.
Threads are an important and tricky part of a multi tasking operating system.
This article will show how to use threads and mutex but will not details thread
design issues such as Deadlock and Spinlock.
Simpe implements Runnable thread.
A simple way to implement a thread is to put it in the same class by
implementing the Runnable interface as follows.
/////////////////////////////////////////////////////////////////////////////
//Class implements a the Runnable interface to create a simple thread
public class ThreadTester implements Runnable
{
//Application runs from here
public static void main( String[] sArgs )
{
//Create the thread object
ThreadTester runner = new ThreadTester();
Thread thread = new Thread( runner );
//Run the thread
System.out.println( "About to Start thread" );
thread.start();
System.out.println( "Thread started!" );
}
//This is the working part of the thread.
//It will loop 10 times displaying a count then terminate
public void run()
{
for( int nCnt = 1; nCnt <= 10; nCnt++ )
System.out.println( "Loop #" + nCnt );
}
}
Extending two Thread objects
Sometimes it is simpler to extend the Thread class to create a worker
thread. In this case we have done just that and added a user member variable.
Extending the Thread class does limit your ability to extend twice
so sometime your may want to create it as an inner class.
//////////////////////////////////////////////////////////////////////////////
//Class creates two extensions of Thread and runs them
public class ThreadTester
{
//Application runs from here
public static void main( String[] sArgs )
{
//Create the thread object
WorkerThread worker1 = new WorkerThread( "Fred" );
WorkerThread worker2 = new WorkerThread( "Barry" );
//Run the thread
System.out.println( "About to Start thread" );
worker1.start();
worker2.start();
System.out.println( "Thread started!" );
}
}
//////////////////////////////////////////////////////////////////////////////
//This is a ninner class the provides a worker thread
class WorkerThread extends Thread
{
private String m_sUser;
//Constructor
public WorkerThread( String sUser )
{
m_sUser = sUser;
}
//This is the working part of the thread.
//It will loop 10 times displaying a count then terminate
public void run()
{
for( int nCnt = 1; nCnt <= 10; nCnt++ )
System.out.println( "Loop (" + m_sUser + ") #" + nCnt );
}
}
Thread syncronisation.
As not all objects are "thread safe" (able to be processed by two
threads at the same time) it is often necessary to stop processing
in a certain area until another thread is finished in that area. In the
example that follows m_nCounter is incremented after an exact match
test is performed. If both threads increment m_nCounter at
the same time 33 could be missed. The synchronized keyword
prevents this happening.
//////////////////////////////////////////////////////////////////////////////
//Class uses synchronsation
public class ThreadTester extends Thread
{
//Attributes
private int m_nCounter = 1;
private String m_sName;
//Application runs from here
public static void main( String[] sArgs )
{
//Create the thread object
ThreadTester worker1 = new ThreadTester( "Fred" );
ThreadTester worker2 = new ThreadTester( "Barry" );
//Run the thread
System.out.println( "About to Start threads" );
worker1.start();
worker2.start();
System.out.println( "Threads started!" );
}
//Constructor
public ThreadTester( String sName )
{
m_sName = sName;
}
//Synchronised function (Only one thread can be in here at any instant
private synchronized boolean areWeDone()
{
if( m_nCounter == 33 )
return true;
m_nCounter++;
return false;
}
//This is the working part of the thread.
//It will loop 10 times displaying a count then terminate
public void run()
{
int nCnt = 0;
while( !areWeDone() )
{
System.out.println( "Loop (" + m_sName + ") #" + nCnt++ );
}
}
}
If m_nCounter was read in one place and incremented in another
part of the SAME class the synchronized( this ) wrapper can be used
to control synchronisation within the SAME class.
synchronized( this )
{
if( m_nCounter == 33 )
return true;
return false;
}
//... Somewhere alse in the SAME class.
synchronized( this )
{
m_nCounter++;
}
No other thread can enter ANY synchronized( this )
section in the class until ALL the synchronized( this )
sections in that class have been exited by all threads.
In contrast to this, other threads can occupy other synchronized
functions in the same class but two threads CAN NOT occupy the
same synchronized function at the same time.
|