多線程總結

1、線程thread中有幾個方法來對線程進行控制:下面介紹幾個比較經常使用到的java

方法 介紹
join 等待某個線程執行完成之後,在執行另外一個線程
sleep 讓某個線程睡眠某個時間
yield 讓某一個線程稍等一下

 

 

 

 

下面是一個join方法例子:git

package org.pan.duoxian.cheng.pojos;

public class PrintCharJoin implements Runnable{
	private Character c;
	private Integer i;
	
	public PrintCharJoin(Character c, Integer i) {
		super();
		this.c = c;
		this.i = i;
	}

	@Override
	public void run() {
		Thread t4 = new Thread(new PrintNum(2000, 100));
		t4.start();
		for(int j=0;j<i;j++){
			if(j==60){
				try {
					t4.join();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.print(this.c+""+j+",");
		}
	}

}

2、線程的同步dom

線程的同步有三種方式:ide

一、synchronized關鍵字:synchronized能夠加到方法裏或者某個資源上來同步線程。工具

package org.pan.duoxian.cheng.main;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 利用synchronized關鍵字加同步鎖的兩種方式
 * @author Administrator
 *
 */
public class TestAcount {
	private static Account account = new Account();
	
	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		
		for(int i=0;i<100;i++){
			System.out.println("-----------------這是第"+i+"個線程");
			executor.execute(new AddPenny(i));
		}
		
		executor.shutdown();
		
		while(!executor.isTerminated()){
			
		}
		
		System.out.println(account.getBalance());
	}
	
	public static class AddPenny implements Runnable{
		private int order;
		
		public AddPenny(int order) {
			super();
			this.order = order;
		}

		@Override
		public void run() {
			account.desposit(1,order);
			//同步的其餘方法,同步資源
//			synchronized (account) {
//				account.desposit(1,order);
//			}
		}
	}
	
	public static class Account{
		private int balance = 0;

		public int getBalance() {
			return balance;
		}
		
		//將方法同步
		public synchronized void desposit(int amount, int order){
			int newBalance = this.balance + amount;
			System.out.println(order+"號線程>>>>>>>>>>>>>>>>進入休眠前"+newBalance);
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			this.balance = newBalance;
			System.out.println(order+"號線程<<<<<<<<<<<<<<<<<<進入休眠後"+balance);
		}
	}
}

二、Lock同步鎖ui

package org.pan.duoxian.cheng.main;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 利用lock加鎖同步
 * @author Administrator
 *
 */
public class TestAcountLock {
	private static Account account = new Account();
	
	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		
		for(int i=0;i<100;i++){
			System.out.println("-----------------這是第"+i+"個線程");
			executor.execute(new AddPenny(i));
		}
		
		executor.shutdown();
		
		while(!executor.isTerminated()){
			
		}
		
		System.out.println(account.getBalance());
	}
	
	public static class AddPenny implements Runnable{
		private int order;
		
		public AddPenny(int order) {
			super();
			this.order = order;
		}

		@Override
		public void run() {
			account.desposit(1,order);
		}
	}
	
	public static class Account{
		private static Lock lock = new ReentrantLock();
		private int balance = 0;

		public int getBalance() {
			return balance;
		}
		
		
		public void desposit(int amount, int order){
			lock.lock();
			System.out.println(order+"號線程>>>>>>>>>>>>>>>>進入休眠前"+balance);
			
			int newBalance = this.balance + amount;
			try {
				Thread.sleep(1);
				this.balance = newBalance;
				
				System.out.println(order+"號線程<<<<<<<<<<<<<<<<<<進入休眠後"+balance);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally{
				lock.unlock();
			}
			
		}
	}
}

三、Semaphore信號量this

package org.pan.duoxian.cheng.main;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * 利用線程管理線程
 * @author panmingshuai
 * @date 建立時間:2017年8月1日 下午10:48:30
 */
public class TestAccountSemaphore {
	private static Account account = new Account();
	
	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		
		for(int i=0;i<100;i++){
			System.out.println("-----------------這是第"+i+"個線程");
			executor.execute(new AddPenny(i));
		}
		
		executor.shutdown();
		
		while(!executor.isTerminated()){
			
		}
		
		System.out.println(account.getBalance());
	}
	
	public static class AddPenny implements Runnable{
		private int order;
		
		public AddPenny(int order) {
			super();
			this.order = order;
		}

		@Override
		public void run() {
			account.desposit(1,order);
		}
	}
	
	public static class Account{
		private static Semaphore semaphore = new Semaphore(1);
		private int balance = 0;

		public int getBalance() {
			return balance;
		}
		
		
		public void desposit(int amount, int order){
			try {
				semaphore.acquire();
				System.out.println(order+"號線程>>>>>>>>>>>>>>>>進入休眠前"+balance);
				
				int newBalance = this.balance + amount;
				
				Thread.sleep(1);
				this.balance = newBalance;
				
				System.out.println(order+"號線程<<<<<<<<<<<<<<<<<<進入休眠後"+balance);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally{
				semaphore.release();
			}
			
		}
	}
}

3、線程之間怎麼通訊spa

線程之間可經過Lock對象獲得的condition對象通訊.net

package org.pan.duoxian.cheng.main;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 利用condition進行線程間通訊
 * @author panmingshuai
 * @date 建立時間:2017年8月1日 下午10:49:14
 */
public class TestAccountCondition {
	private static Account account = new Account();
	
	public static void main(String[] args) {
		ExecutorService excutor = Executors.newFixedThreadPool(2);
		excutor.execute(new Withdraw());
		excutor.execute(new Desposit());
		excutor.shutdown();
	}
	
	public static class Desposit implements Runnable{
		@Override
		public void run() {
			try {
				while(true){
					account.deposit((int)(Math.random()*10)+1);
					Thread.sleep(1000);
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
			
		}
	}
	
	public static class Withdraw implements Runnable{
		@Override
		public void run() {
			while(true){
				account.withdraw((int)(Math.random()*10) + 1);
			}
		}
	}
	
	
	private static class Account{
		private Lock lock = new ReentrantLock();
		private Condition condition = lock.newCondition();
		private int balance = 0;
		
		public int getBalance() {
			return balance;
		}
		
		public void withdraw(int amount){
			lock.lock();
			System.out.println("須要取:"+amount);
			try {
				System.out.println("取錢以前有:"+balance);
				while(balance<amount){
					condition.await();
				}
				System.out.println("不在等待,取錢以前有:"+balance);
				balance -= amount;
				System.out.println("取錢以後有:"+balance);
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				lock.unlock();
			}
		}
		
		public void deposit(int amount){
			lock.lock();
			System.out.println("存了:"+amount);
			try {
				balance += amount;
				System.out.println("存錢以後有:"+balance);
				condition.signalAll();
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				lock.unlock();
			}
		}
	}
}

4、消費者和生產者的例子:線程

package org.pan.duoxian.cheng.main;

import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 利用condition完成消費者和生產者
 * @author panmingshuai
 * @date 建立時間:2017年8月1日 下午10:49:50
 */
public class ConsumerProducer {
	private static Buffer buffer = new Buffer();
	
	public static void main(String[] args) {
		ExecutorService excutor = Executors.newFixedThreadPool(2);
		excutor.execute(new ProducerTask());
		excutor.execute(new ConsumerTask());
		excutor.shutdown();
	}
	
	public static class ProducerTask implements Runnable{
		@Override
		public void run() {
			try {
				int i = 0;
				while(true){
					buffer.write(i++);
					Thread.sleep((int)(Math.random()*2000));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	public static class ConsumerTask implements Runnable{
		@Override
		public void run() {
			try {
				while(true){
					buffer.read();
					Thread.sleep((int)(Math.random()*2000));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	private static class Buffer{
		private static int CAPASITY = 2;
		private LinkedList<Integer> queue = new LinkedList<>();
		
		private Lock lock = new ReentrantLock();
		
		private Condition notfull = lock.newCondition();
		private Condition notempty = lock.newCondition();
		
		public void write(int value){
			lock.lock();
			
			try {
				while(queue.size() == CAPASITY){
					notfull.await();
				}
				
				queue.offer(value);
				System.out.println("寫入了:"+value);
				notempty.signal();
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				lock.unlock();
			}
		}
		
		public int read(){
			int value = 0;
			lock.lock();
			
			try {
				while(queue.isEmpty()){
					notempty.await();
				}
				
				value = queue.remove();
				System.out.println("取走了:"+value);
				notfull.signal();
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				lock.unlock();
			}
			return value;
		}
	}
}

6、死鎖的例子:

package org.pan.duoxian.cheng.main;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 死鎖的例子
 * @author panmingshuai
 * @date 建立時間:2017年8月1日 下午10:55:22
 */
public class TestDeadLock {
	private static Account account = new Account();
	
	public static void main(String[] args) {
		ExecutorService excutor = Executors.newFixedThreadPool(2);
		excutor.execute(new Withdraw());
		excutor.execute(new Desposit());
		excutor.shutdown();
	}
	
	public static class Desposit implements Runnable{
		@Override
		public void run() {
			try {
				while(true){
					account.deposit((int)(Math.random()*10)+1);
					Thread.sleep(1000);
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
			
		}
	}
	
	public static class Withdraw implements Runnable{
		@Override
		public void run() {
			while(true){
				account.withdraw((int)(Math.random()*10) + 1);
			}
		}
	}
	
	
	private static class Account{
		private Lock lockBalance = new ReentrantLock();
		private Lock lockWater = new ReentrantLock();
		
		private int balance = 0;
		private int water = 0;
		
		public int getBalance() {
			return balance;
		}
		
		public int getWater() {
			return water;
		}

		public void withdraw(int amount){
			try {
				lockBalance.lock();
				System.out.println("withdraw:get:balance");
				Thread.sleep(1000);
				
				lockWater.lock();
				Thread.sleep(1000);
				System.out.println("withdraw:get:water");
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				lockWater.unlock();
				lockBalance.unlock();
			}
		}
		
		public void deposit(int amount){
			try {
				lockWater.lock();
				Thread.sleep(1000);
				System.out.println("desposit:get:water");
				lockBalance.lock();
				Thread.sleep(1000);
				System.out.println("desposit:get:balance");
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				lockBalance.unlock();
				lockWater.unlock();
			}
		}
	}
}

上述的例子能夠直接拷到工具裏運行,只須要改改包名就好了

若是仍是以爲麻煩,馬雲的地址爲:https://git.oschina.net/panmingshuai/cheng.git

相關文章
相關標籤/搜索