Skip to content

Instantly share code, notes, and snippets.

@yclim95
Last active January 4, 2024 05:36
Show Gist options
  • Save yclim95/d8043171e70b92ad5ef74e861cf53f43 to your computer and use it in GitHub Desktop.
Save yclim95/d8043171e70b92ad5ef74e861cf53f43 to your computer and use it in GitHub Desktop.
Java Multi-Threading Part I

#Java Multi-Threading Part I

##Lesson1 : Basic Threads ###1. Extends Thread

/*
 * Basic Threads
 * Run Concurently(Simultaneously)
 */
public class App {

	public static void main(String[] args) {
		Runner runner1 = new Runner();
		runner1.start(); //Reason use start() ==> want to run Simultaneously
		
		Runner runner2 = new Runner();
		runner2.start();
	}//ENDof Main
}

class Runner extends Thread{

	@Override
	public void run() {
		for(int i = 0; i < 10; i++){
			System.out.println("Hello: " + i);
			try {
				Thread.sleep(100); //in MilliSeconds
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}//ENDof run
	
}

OUTPUT

Hello: 0
Hello: 0
Hello: 1
Hello: 1
Hello: 2
Hello: 2
Hello: 3
Hello: 3
Hello: 4
Hello: 4
Hello: 5
Hello: 5
Hello: 6
Hello: 6
Hello: 7
Hello: 7
Hello: 8
Hello: 8
Hello: 9
Hello: 9

###2. Implement Runnable

/*
 * Basic Threads
 * Run Concurently(Simultaneously)
 */
public class App {

	public static void main(String[] args) {
		Thread thread1 = new Thread(new Runner());
		thread1.start(); //Reason use start() ==> want to run Simultaneously
		
		Thread thread2 = new Thread(new Runner());
		thread2.start();
	}//ENDof Main
}

//Implements Runnable 
class Runner implements Runnable{

	@Override
	public void run() {
		for(int i = 0; i < 10; i++){
			System.out.println("Hello: " + i);
			try {
				Thread.sleep(100); //in MilliSeconds
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}//ENDof run
	
}

OUTPUT

Hello: 0
Hello: 0
Hello: 1
Hello: 1
Hello: 2
Hello: 2
Hello: 3
Hello: 3
Hello: 4
Hello: 4
Hello: 5
Hello: 5
Hello: 6
Hello: 6
Hello: 7
Hello: 7
Hello: 8
Hello: 8
Hello: 9
Hello: 9

###2. Shorter(implements Runnable())

/*
 * Basic Threads
 * Run Concurently(Simultaneously)
 */
public class App {

	public static void main(String[] args) {
		Thread thread1 = new Thread(new Runnable(){

			@Override
			public void run() {
				for(int i = 0; i < 10; i++){
					System.out.println("Hello: " + i);
					try {
						Thread.sleep(100); //in MilliSeconds
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}//ENDof RUN
		});
		
		thread1.start(); //Reason use start() ==> want to run Simultaneously
	}//ENDof Main
}

OUTPUT

Hello: 0
Hello: 1
Hello: 2
Hello: 3
Hello: 4
Hello: 5
Hello: 6
Hello: 7
Hello: 8
Hello: 9

##Lesson2 : Basic Threads Synchronization

###Problem Encountered ??

/*
 * Basic Threads Synchronization 
 * Run Concurently(Simultaneously)
 */
/*
 * 2 Problems : 
 * Sharing more than 1 threads --> Sharing the same DATA
 */

public class App {

	public static void main(String[] args) {
		Processor proc1 = new Processor();
		proc1.start();
	}//ENDof Main
}

class Processor extends Thread{

	@Override
	public void run() {
		while(true){ //Infinite Loop
			System.out.println("Hello");
			try {
				Thread.sleep(100);//MilliSeconds 
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
		}
	}//Endof RUN 
	
}

Al'right look at the code below on how to terminate the processor by using Thread interruptions.

###Solution 1 : Use "Volatile" keywords volative is used to prevent threads from caching variables.

/*
 * Basic Threads Synchronization 
 * Run Concurently(Simultaneously)
 */
/*
 * 2 Problems : 
 * Sharing more than 1 threads --> Sharing the same DATA
 */

public class App {

	public static void main(String[] args) {
		Processor proc1 = new Processor();
		proc1.start();
	}//ENDof Main
}

class Processor extends Thread{

	@Override
	public void run() {
		while(true){ //Infinite Loop
			System.out.println("Hello");
			try {
				Thread.sleep(100);//MilliSeconds 
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
		}
	}//Endof RUN 
	
}

###Solution 2: Synchronized Keyword

/*
 * Synchronized Keyword
 * Run Concurently(Simultaneously)
 */
/*
 * 2 Problems : 
 * Sharing more than 1 threads --> Sharing the same DATA
 */

public class App {
	private int count = 0;
	
	public static void main(String[] args) {
		App app = new App();
		app.doWork();
	}//ENDof Main
	
	//
	//Use SYNCHRONIZED ///////////////
	public synchronized void increment(){
		count++;
	}
	public void doWork(){
		Thread thread1 = new Thread(new Runnable(){

			@Override
			public void run() {
				for (int i = 0; i < 10000; i++){
					increment();
				}
			}
			
		});
		
		Thread thread2 = new Thread(new Runnable(){

			@Override
			public void run() {
				for (int i = 0; i < 10000; i++){
					increment();
				}
			}
			
		});
		
		thread1.start();
		thread2.start();
		
		//Wait for the thread to Finish 
		try {
			thread1.join();
			thread2.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("Count is " + count);
	}//ENDof doWork()
}

OUTPUT

Count is 20000

##Lesson3 : Multiple Locks => Use Synchronized Code Blocks

###1. Simple Worker.java

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Worker {

	private Random random = new Random();
	private List<Integer> list1 = new ArrayList<Integer>();
	private List<Integer> list2 = new ArrayList<Integer>();

	public void stageOne() {
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		list1.add(random.nextInt(100));
	}

	public void stageTwo() {
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		list2.add(random.nextInt(100));
	}
	
	public void process(){
		for(int i = 0; i < 1000; i++){
			stageOne();
			stageTwo();
		}
	}
	public void main() {
		System.out.println("Starting ....");
		long start = System.currentTimeMillis();
		process();
		long end = System.currentTimeMillis();
		
		System.out.println("Time take: " + (end-start) + " ms");
		System.out.println("List 1 Length: " + list1.size() +
				"; List 2 Length: " + list2.size());
	}
}

App.java

/*
 * Multiple Locks: Use of Synchronized Code Blocks
 * Run Concurently(Simultaneously)
 */

public class App {
	
	public static void main(String[] args) {
		new Worker().main();
	}//ENDof Main
}

OUTPUT

Starting ....
Time take: 2850 ms
List 1 Length: 1000; List 2 Length: 1000

###2. A Little Better (Process @ the same time)... Worker.java

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Worker {

	private Random random = new Random();
	private List<Integer> list1 = new ArrayList<Integer>();
	private List<Integer> list2 = new ArrayList<Integer>();

	//Synchronized => Enquire the monitor log => Slow process 
	public synchronized void stageOne() {
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		list1.add(random.nextInt(100));
	}

	public synchronized void stageTwo() {
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		list2.add(random.nextInt(100));
	}
	
	public void process(){
		for(int i = 0; i < 1000; i++){
			stageOne();
			stageTwo();
		}
	}
	public void main() {
		System.out.println("Starting ....");
		long start = System.currentTimeMillis();
		
		Thread t1 = new Thread(new Runnable(){

			@Override
			public void run() {
				process();
			}
			
		});
				
		Thread t2 = new Thread(new Runnable(){

			@Override
			public void run() {
				process();
			}
			
		});
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		
		System.out.println("Time take: " + (end-start) + " ms");
		System.out.println("List 1 Length: " + list1.size() +
				"; List 2 Length: " + list2.size());
	}
}

OUTPUT

Starting ....
Time take: 5763 ms
List 1 Length: 2000; List 2 Length: 2000

###3. Slow Proces ???...... Use this

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Worker {

	private Random random = new Random();
	private Object lock1 = new Object();
	private Object lock2 = new Object();
	private List<Integer> list1 = new ArrayList<Integer>();
	private List<Integer> list2 = new ArrayList<Integer>();
	
	/*
	 * Multiple Locks: Use of Synchronized Code Blocks
	 * Run Concurently(Simultaneously)
	 */
	
	//Synchronized => Enquire the monitor log => Slow process 
	//Having Multiple Threads will slow down 
	// So.... use this method to ... make the process a little faster
	public void stageOne() {
		//Only 1 Thread @ a time -> Faster process
		synchronized(lock1){
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			list1.add(random.nextInt(100));
		}
	}

	public synchronized void stageTwo() {
		//Only 1 Thread @ a time -> Faster process
		synchronized(lock2){
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			list2.add(random.nextInt(100));
		}
	}
	
	public void process(){
		for(int i = 0; i < 1000; i++){
			stageOne();
			stageTwo();
		}
	}
	public void main() {
		System.out.println("Starting ....");
		long start = System.currentTimeMillis();
		
		Thread t1 = new Thread(new Runnable(){

			@Override
			public void run() {
				process();
			}
			
		});
				
		Thread t2 = new Thread(new Runnable(){

			@Override
			public void run() {
				process();
			}
			
		});
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		
		System.out.println("Time take: " + (end-start) + " ms");
		System.out.println("List 1 Length: " + list1.size() +
				"; List 2 Length: " + list2.size());
	}
}

OUTPUT

Starting ....
Time take: 2852 ms
List 1 Length: 2000; List 2 Length: 2000

##Resources

  1. Click Here to JAVA MultiThreading Part II
  2. Main Contents
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment