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