Process: executed computer program with program code and activities such as machine code, memory (code, data, call stack, heap), and state (register content, program counter, stack pointer)
Thread: smallest sequence of program by a scheduler, a single path of execution within a process, share resources within a process address space. “lightweight processes”.
Threads communicate through shared memory, while processes use IPC (inter-process communication which needs to swap out a memory space)
1. Extend Thread subclass and run method, which extend only one class Thread public class LetterThread extends Thread { Private char character; Public LetterThread( char character ) { This.character = character; } public void run() { for( int counter = 0; counter < 100; counter++ ) { System.out.print( this.character + “ ” ); } } } public class CounterThread extends Thread { public void run() { for( int counter = 1; counter <= 100; counter++ ) { System.out.print( counter + “ ” ); } } } public class Client { public static void main( String[] args ) { LetterThread a = new LetterThread( ‘a’ ); LetterThread b = new LetterThread( ‘b’ ); CounterThread c = new CounterThread(); a.start(); b.start(); c.start(); } } ps. a.SetPriority(Thread.MAX_PRIORITY) can’t set the priority explicitly
2. Implement Runnable interface: create new thread with runnable instance using class hierarchy to define own instance of thread accessing common resources. CustomRunnable r = new CustomRunnable(); new Thread( r ).start(); new Thread( r ).start(); (reusing r in any state shared among the running two threads)
public class LetterRunnable implements Runnable { private char character; public LetterRunnable( char character ) { this.character = character; } public void run() { for( int counter = 0; counter < 100; counter++ ) { System.out.print( this.character + “ ” ); } } } public class CounterRunnable implements Runnable { public void run() { for( int counter = 1; counter <= 100; counter++ ) { System.out.print( counter + “ ” ); } } } public class Client { public static void main( String[] args ) { LetterRunnable a = new LetterRunnable( ‘a’ ); LetterRunnable b = new LetterRunnable( ‘b’ ); CounterRunnable c = new CounterRunnable();
new Thread( a ).start(); new Thread( b ).start(); new Thread( c ).start(); } }
Thread States
Thread Created | ------------------------------------------------- v v | new --startà ready ------------stop--------à finished | | ^ / | | | | / | | run yield/expired stop/complete | | | | / | | v | / | | running --suspend/sleep/wait----à blocked
void run(): Invoked by Java runtime system to execute the thread. (To be overrided) void start(): starts the thread to be run, called by runnable object in the client class static void sleep( long milliseconds ) throws InterruptedException: put runnable object to sleep public final void join() throws InterruptedException: allows one thread to wait for completion
Synchronization: avoid possible corruption when multiple threads simultaneously access public synchronized void someMethod() { }
When one thread is running synchronized method for an object, all other threads invoking synchronized methods for same object will be blocked/suspended.
Constructors can’t be synchronized.
Locks (using synchronized method): a thread waits and acquires lock beforehand for exclusive and consistent access to an object’s state and releases the lock when done. Lock is used on the class object with a static synchronized method declaration
public class PiggyBank { private int balance = 0; public int getBalance() { return this.balance; } public void setBalance( int newBalance ) { this.balance = newBalance; } }
public class PiggyBankDriver { public static void main( String[] args ) throws InterruptedException { final int count = 100; PiggyBank bank = new PiggyBank(); Thread pennies[] = new Thread[ count ]; for( int i = 0; i < count; i++ ) { pennies[ i ] = new AddAPennyThreadSynchronized( bank ); pennies[ i ].start(); } for( int i = 0; i < count; i++ ) { pennies[i].join(); } System.out.println( “After adding “ + count + “ pennies, balance is “ + bank.getBalance() ); } }
public class AddAPennyThreadSynchronized extends Thread { private PiggyBank bank;
public AddAPennyThreadSynchronized( PiggyBank bank ) { this.bank = bank; } private static synchronized void addAPenny( PiggyBank bank ) { int newBalance = bank.getBalance() + 1; try { Thread.sleep( 5 ); } catch( InterruptedException e ) { System.out.println( “Interrupted” ); } bank.setBalance( newBalance ); } public void run() { addAPenny( this.bank ); } }
Sample Outputs
>make find . –type f –name ‘*.class’ –delete javac PiggyBankDriver.java; java PiggyBankDriver After adding 100 pennies, balance is 100