Threads in Java

We need to control access to shared state ( when multiple threads are at work ), to avoid unexpected results.

In the case of the program below the shared state is the int sheepCount.

10 different threads call the method incrementAndReport() .

Without thread management 

public class Ch18SheepManager {

	  private int sheepCount = 0;

	  private void incrementAndReport() {

		    Thread t = Thread.currentThread();		    
		    System.out.print("sheepcount = " + (++sheepCount) + "	Worker    - " + t.getName());										

	  }

	  public static void main(String[] args) throws Exception {
		
		    var service = Executors.newFixedThreadPool(20);
		    var manager = new Ch18SheepManager();

		    for (int i = 0; i < 10; i++)
			     service.submit(() -> manager.incrementAndReport());
		
	  }

}

Output ( wonky )

Every thread is trying to get access to the method incrementAndReport() , and its all over the place

sheepcount = 5	Worker    - pool-1-thread-5sheepcount = 2	Worker    - pool-1-thread-3sheepcount = 4	Worker    - pool-1-thread-2sheepcount = 1	Worker    - pool-1-thread-4sheepcount = 3	Worker    - pool-1-thread-1

sheepcount = 7	Worker    - pool-1-thread-7sheepcount = 6	Worker    - pool-1-thread-6
sheepcount = 8	Worker    - pool-1-thread-8
sheepcount = 9	Worker    - pool-1-thread-9
sheepcount = 10	Worker    - pool-1-thread-10

 

With Thread access management

Each time the method is called by a Thread, its completed by that Thread (other threads locked out until finished)

sheepcount = 1	Worker    - pool-1-thread-1
sheepcount = 2	Worker    - pool-1-thread-5
sheepcount = 3	Worker    - pool-1-thread-6
sheepcount = 4	Worker    - pool-1-thread-4
sheepcount = 5	Worker    - pool-1-thread-3
sheepcount = 6	Worker    - pool-1-thread-2
sheepcount = 7	Worker    - pool-1-thread-8
sheepcount = 8	Worker    - pool-1-thread-7
sheepcount = 9	Worker    - pool-1-thread-9
sheepcount = 10	Worker    - pool-1-thread-10

 

This is done with the help of the keyword synchronized

public class Ch18SheepManager {

	  private int sheepCount = 0;
	  Object lock = new Object(); /* created once here, so every thread gets SAME obj */

	  // synchronized  /* we could do this */
	  private void incrementAndReport() {

		    // Object lock = new Object(); DONT DO THIS
		    // synchronized(this) {  /* we could do this */
		    synchronized (lock) {
			      Thread t = Thread.currentThread();
			      System.out.print("sheepcount = " + (++sheepCount) + "	Worker    - " + t.getName());								
		    }

	  }

	  public static void main(String[] args) throws Exception {
		
		    var service = Executors.newFixedThreadPool(20);
		    var manager = new Ch18SheepManager();

		    for (int i = 0; i < 10; i++)
			      service.submit(() -> manager.incrementAndReport());
		
	  }

}

 

important ( see DONT DO THIS )

Don’t use a local method variable to synchronize on :

as it will be a new variable for every thread and the lock won’t work

 

 

Some notes for Oracle cert (OCPJP 11 ), I’ve currently studying for (last time I did a Java cert Sun Microsystems was the vendor yikes !).

This is based on a program in the Jeanne Boyarsky / Scott Selikoff book

2 thoughts on “Threads in Java”

Leave a Comment