markdown Java MultiThreading第三部分

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Java MultiThreading第三部分相关的知识,希望对你有一定的参考价值。

#Java MultiThreading Part III

##Lesson 8 : Example on using (low level synchronization)

**Processor.java**
```java
import java.util.LinkedList;
import java.util.Random;

public class Processor {
	private LinkedList <Integer> list = new LinkedList<Integer>();
	private final int LIMIT = 10;
	private Object lock = new Object(); //LockOn 
	
	public void produce() throws InterruptedException{
		int value = 0;
		
		while(true){ //Infinite Loop
			synchronized(lock){
				while(list.size() == LIMIT){
					//wait until the current thread invoke notify()
					lock.wait();  //No1
				}
				list.add(value ++);
				lock.notify(); // Will wake up the consume() @ No2
			}
		}
		
	}//Endof Produce()
	
	public void consume() throws InterruptedException{
		Random random = new Random();
		
		while(true){
			synchronized(lock){
				
				while(list.size() == 0){
					lock.wait(); //No2
				}
				System.out.print("List size: " + list.size());
				int value = list.removeFirst();
				System.out.println("; value: " + value);
				lock.notify(); // Will wake up thread @ No1
				
			}//EndOf Synchronized()
			
			Thread.sleep(random.nextInt(1000)); //0-999
		}//Endof While
		
	}//Endof Consume()
}
```

**App.java**
```java
/*
 * Low Level Synchronization (Example) 
 * Run Concurently(Simultaneously)
 */

public class App {
	
	public static void main(String[] args) throws InterruptedException {
		final Processor processor = new Processor();
		Thread t1 = new Thread(new Runnable(){

			@Override
			public void run() {
				try {
					processor.produce();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		});
		
		Thread t2 = new Thread(new Runnable(){

			@Override
			public void run() {
				try {
					processor.consume();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		});
		
		//Start
		t1.start();
		t2.start();
		
		t1.join();
		t2.join();
	}//ENDof Main
	
}
```

**OUTPUT**
```
List size: 10; value: 0
List size: 10; value: 1
List size: 10; value: 2
List size: 10; value: 3
List size: 10; value: 4
List size: 10; value: 5
List size: 10; value: 6
List size: 10; value: 7
List size: 10; value: 8
List size: 10; value: 9
List size: 10; value: 10
List size: 10; value: 11
List size: 10; value: 12
List size: 10; value: 13
List size: 10; value: 14
List size: 10; value: 15
List size: 10; value: 16
List size: 10; value: 17

```

##Lesson 9 : Re-entrants Locks Class (Al-ternative using Synchronize Keywords)

**Runner.java**
```java
import java.util.Scanner;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Runner {
	private int count = 0;
	private Lock lock = new ReentrantLock(); //Alternative to Synchronized
	private Condition condition = lock.newCondition();
	
	private void increment(){
		for (int i = 0; i < 1000; i++){
			count++;
		}
	}
	public void firstThread() throws InterruptedException{
		lock.lock();
		
		System.out.println("Waiting...");
		condition.await();  //Wait until signal() is invoked (No1)
		
		System.out.println("Woken Up!");
		try {
			increment(); //Use try-catch => prevent Exception 
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
		
	}
	
	public void secondThread() throws InterruptedException{
		Thread.sleep(1000);
		lock.lock();
		
		System.out.println("Press The return key!");
		new Scanner(System.in).nextLine();
		System.out.println("Got return key!");
		
		condition.signal(); //No1
		try {
			increment(); //Use try-catch => prevent Exception 
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	
	public void finished(){
		System.out.println("Count: " + count);
	}
}
```

**App.java**
```java
/*
 * Re-entrants Locks
 * Run Concurently(Simultaneously)
 */

public class App {
	
	public static void main(String[] args) throws InterruptedException {
		final Runner runner = new Runner();
		Thread t1 = new Thread(new Runnable(){

			@Override
			public void run() {
				try {
					runner.firstThread();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		});
		
		Thread t2 = new Thread(new Runnable(){

			@Override
			public void run() {
				try {
					runner.secondThread();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		});
		
		//Start
		t1.start();
		t2.start();
		
		t1.join();
		t2.join();
		
		runner.finished();
	}//ENDof Main
	
}
```

**OUTPUT**
```
Waiting...
Press The return key!

Got return key!
Woken Up!
Count: 2000

```

##Lesson 10 : DeadLock Occured .... How to Solved it ?

**Runner.java**
```java
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Runner {	
	private Account acc1 = new Account();
	private Account acc2 = new Account();
	
	private Lock lock1 = new ReentrantLock();
	private Lock lock2 = new ReentrantLock();
	
	//Solution --> To DeadLock 
	private void acquireLocks(Lock lock1, Lock lock2) throws InterruptedException{
		while(true){
			//Acquire Lock
			Boolean gotFirstLock = false;
			Boolean gotSecondLock = false;
			
			try{
				gotFirstLock = lock1.tryLock(); //Return true if have
				gotSecondLock = lock2.tryLock();
			}finally{
				if (gotFirstLock && gotSecondLock){
					return;
				}
				
				if (gotFirstLock){
					lock1.unlock();
				}
				
				if (gotSecondLock){
					lock2.unlock();
				}
			}
			
			//Lock not acquired
			Thread.sleep(1);
		}
	}
	public void firstThread() throws InterruptedException{	
		Random random = new Random();
		 
		for (int i = 0; i < 1000; i++){
			acquireLocks(lock1,lock2);
			try{
				Account.transfer(acc1, acc2, random.nextInt(100)); //Transfer range(0-99)
			}finally{
				lock1.unlock();
				lock2.unlock();
			}
		}
	}//EndOf firstThread()
	
	public void secondThread() throws InterruptedException{
		Random random = new Random();
		 
		for (int i = 0; i < 1000; i++){
			/*
			 * Dead Lock (Did not lock in the same Order)
			 * 
			 * lock2.lock(); 
			 * lock1.lock();
			 */
			acquireLocks(lock2,lock1);
			try{
				Account.transfer(acc2, acc1, random.nextInt(100)); //Transfer range(0-99)
			}finally{
				lock1.unlock();
				lock2.unlock();
			}
		}
	}//EndOf secondThread()
	
	public void finished(){
		System.out.println("Account 1 Balance: " + acc1.getBalance());
		System.out.println("Account 2 Balance: " + acc2.getBalance());
		System.out.println("Total Account Balance: " + (acc1.getBalance() + acc2.getBalance()) );
	}//EndOf Finished()
}
```

**Account.java**
```java
public class Account {
	private int balance = 1000;
	
	public void deposit(int amount){
		balance += amount;
	}
	
	public void withdraw(int amount){
		balance -= amount;
	}
	
	public int getBalance(){
		return balance;
	}
	
	public static void transfer(Account acc1, Account acc2, int amount){
		acc1.withdraw(amount);
		acc2.deposit(amount);
	}
}
```

**App.java**
```java
/*
 * DeadLock
 * Run Concurently(Simultaneously)
 */

public class App {
	
	public static void main(String[] args) throws InterruptedException {
		final Runner runner = new Runner();
		Thread t1 = new Thread(new Runnable(){

			@Override
			public void run() {
				try {
					runner.firstThread();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		});
		
		Thread t2 = new Thread(new Runnable(){

			@Override
			public void run() {
				try {
					runner.secondThread();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		});
		
		//Start
		t1.start();
		t2.start();
		
		t1.join();
		t2.join();
		
		runner.finished();
	}//ENDof Main
	
}
```

**OUTPUT**
```
Account 1 Balance: 2266
Account 2 Balance: -266
Total Account Balance: 2000
```

##Lesson 11 : Semaphores

###1. Introduce Semaphores Class(object)

**Semaphore** :
```
Mainly used to limit the number of simultaneous threads that can access a resources, but you can also use them to implement deadlock recovery systems since a semaphore with one permit is basically a lock that you can unlock from other threads.
```

**App.java**
```java
import java.util.concurrent.Semaphore;

/*
 * Semaphores
 * Run Concurently(Simultaneously)
 */

public class App {
	
	public static void main(String[] args) throws InterruptedException {
		Semaphore semaphore = new Semaphore(1);
		
		semaphore.release(); // +1 permits
		semaphore.acquire(); // -1 permits
		
		System.out.println(semaphore.availablePermits()); //1
	}//ENDof Main
	
}
```

**OUTPUT**
```
1

```


###2. How to use Semaphores Class(object)

**Connection.java**
```java
import java.util.concurrent.Semaphore;

public class Connection {
	private static Connection instance = new Connection();
	private int connections = 0;
	//Semaphore
	private Semaphore sempahore = new Semaphore(10);
	
	private Connection(){
		
	}
	
	public static Connection getConnection(){
		return instance;
	}
	
	public void connect(){
		try {
			sempahore.acquire(); // -1
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		
		try{
			doConnect();
		}finally{
			sempahore.release(); // +1
		}
	}
	
	public void doConnect(){
		
		synchronized(this){
			connections++;
			System.out.println("Current Connections: " + connections);
		}
		
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		synchronized(this){
			connections--;
		}
		
		
	}//ENDof Connect()
}
```

**App.java**
```java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/*
 * Semaphores
 * Run Concurently(Simultaneously)
 */

public class App {

	public static void main(String[] args) throws InterruptedException {

		ExecutorService executor = Executors.newCachedThreadPool();

		for (int i = 0; i < 200; i++) {
			// submit => Create a new thread auto
			executor.submit(new Runnable() {

				@Override
				public void run() {
					Connection.getConnection().connect(); //Invoke
				}

			});
		}//ENDof For loop
		
		executor.shutdown();
		executor.awaitTermination(1, TimeUnit.DAYS); //Wait for 1 day then ONLY terminate
	}// ENDof Main

}
```

**OUTPUT**
```
Current Connections: 1
Current Connections: 2
Current Connections: 3
Current Connections: 4
Current Connections: 5
Current Connections: 6
Current Connections: 7
Current Connections: 8
Current Connections: 9
Current Connections: 10
Current Connections: 1
Current Connections: 2
Current Connections: 3
Current Connections: 4
Current Connections: 5
Current Connections: 6
Current Connections: 7
Current Connections: 8
Current Connections: 9
Current Connections: 10
Current Connections: 1
Current Connections: 2
Current Connections: 3
Current Connections: 4
Current Connections: 5
Current Connections: 6
Current Connections: 7
Current Connections: 8
Current Connections: 9
Current Connections: 10
Current Connections: 1
Current Connections: 2
Current Connections: 3
Current Connections: 4
Current Connections: 5
Current Connections: 6
Current Connections: 7
Current Connections: 8
Current Connections: 9
Current Connections: 10

```


##Resources
1. [Click Here to Java MultiThreading Part IV](https://gist.github.com/yclim95/b17af7623b45a1bd46b04342fffa4941)
2. [Back to JAVA MultiThreading Part II](https://gist.github.com/yclim95/6aa4e8faa7b80f6bff681aa3a36ae596)
3. [Main Contents](https://gist.github.com/yclim95/821d7059767dfc098eaa6698490bb1a0)

以上是关于markdown Java MultiThreading第三部分的主要内容,如果未能解决你的问题,请参考以下文章

python multithread task_done

MultiThread(VS2013 MFC多线程-含源码-含个人逐步实现文档)

多线程--MultiThread

Multithread 什么时候处理多线程,有几种方式,优缺点?

MultiThread SkinnedMeshRenderer原理及实现

MultiThread SkinnedMeshRenderer原理及实现