Java多線程幾個例子學習

Java多線程例子學習

1.比賽要開始了,5名運動員來到了跑道前。隨着發令槍一響,大家都拼命往終點跑去。當所有人都到達終點時,比賽結束!
代碼:
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletionService {

	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		final CountDownLatch begin = new CountDownLatch(1);  //開始的倒數鎖
		final CountDownLatch end = new CountDownLatch(5);  //結束的倒數鎖
		final ExecutorService executorService = Executors.newFixedThreadPool(5);
		
		for(int i = 0;i<5;i++){
			final int No = i +1;
			Runnable run = new Runnable(){
				public void run() {
					try{
						begin.await();
						Thread.sleep(new Random().nextInt(10000));
						System.out.println("No."+No+"到達終點!");
					}catch(Exception e){
						e.printStackTrace();
					}finally{
						end.countDown();
					}
				}
				
			};
			executorService.submit(run);
		}
		System.out.println("比賽開始....");
		begin.countDown();
		end.await();
		System.out.println("比賽結束!");
		executorService.shutdown();
	}
}
主要是對CountDownLatch和ExecutorService,Java併發包中的兩個類的學習!
2.包租婆終於把她的十個房間出租出去了,一個月後去收租,每個房客將其本月收入的 10% 上交!
代碼:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

class Renter implements Callable<Integer>{

	private int roomNumber;
	public Renter(int roomNumberArgs){
		this.roomNumber = roomNumberArgs;
	}
	@Override
	public Integer call() throws Exception {
		Random  random = new Random();
		Thread.sleep(1000*random.nextInt(5));
		int rent = 1000*random.nextInt(10);
		System.out.println((roomNumber+1)+"房支付房租"+rent);
		return rent;
	}
}
public class Rentor {
	public static void main(String[] args) throws InterruptedException, ExecutionException{
		ExecutorService executorService = Executors.newFixedThreadPool(10);
		List<Callable<Integer>> taskList = new ArrayList<Callable<Integer>>();
		for(int i = 0;i<10;i++){
			taskList.add(new Renter(i));
		}
		List<Future<Integer>> futureList = executorService.invokeAll(taskList);
		executorService.shutdown();
		int total = 0;
		for(Future<Integer> future : futureList){
			total += future.get();
		}
		System.out.println("一共收到房租"+total);
	}
}
3.門戶網站首頁要顯示今日頭條、娛樂新聞、社會新聞、體育新聞。爲了加快顯示速度,在接到用戶請求後,將各頻道的查詢交給子線程,最後在彙總並渲染頁面
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

class DAO implements Callable<String>{
	public String name;

	public DAO(String nameArgs){
		this.name = nameArgs;
	}
	@Override
	public String call() throws Exception {
		Random random = new Random();
		Thread.sleep(1000*random.nextInt(5));
		System.out.println(name+"完成查詢");
		return name + "列表";
	}
}
public class WebSite {
	
	public  static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException{
		FutureTask<String> todayHotNews = new FutureTask<String>(new DAO("TodayHotNews"));
		new Thread(todayHotNews).start();
		FutureTask<String> socialNews = new FutureTask<String>(new DAO("socialNews"));
		new Thread(socialNews).start();
		FutureTask<String> entainmentNews = new FutureTask<String>(new DAO("entainmentNews"));
		new Thread(entainmentNews).start();
		
		System.out.println("處理登錄狀態......");
		System.out.println("......處理其他的任務......");
		Thread.sleep(1000*3);
		System.out.println(".....其他任務處理完成......");
		
		System.out.println(todayHotNews.get(1, TimeUnit.MINUTES));
		System.out.println(socialNews.get(1, TimeUnit.MINUTES));
		System.out.println(entainmentNews.get(1, TimeUnit.MINUTES));
		
		System.out.println("完成頁面渲染!");
	}
}
4.省博物館借來了達芬奇的畫作舉辦畫展,爲保證秩序以及畫作的安全,館長決定讓觀衆分批參觀,每批只放5個人進館參觀,出去幾人才能再放幾人進來。
代碼:
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;


public class Exhibition {

	/**
	 * @param args
	 */
	public static void main(String[] args){

		ExecutorService executorService = Executors.newCachedThreadPool();
		final Semaphore semaphore = new Semaphore(5);
		for(int i = 0;i<20;i++){
			final int NO = i +1;
			Runnable run = new Runnable(){
				@Override
				public void run() {
					try {
						semaphore.acquire();
						Random r  = new Random();
						System.out.println("No."+NO+"遊客開始參觀!");
						Thread.sleep(1000*r.nextInt(10));
						System.out.println("No."+NO+"遊客參觀完畢!");
						semaphore.release();
					}
					catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
			executorService.execute(run);
		}
		executorService.shutdown();
	}
}
信號量的學習!
5.財務軟件中的會計憑證上有一個流水號。此流水號爲防止作弊,必須是連續的,不能有重號、斷號。現在你要實現這個流水號分配功能,要求大高併發下,流水號分配不能有錯!
代碼:
public class RunningNumber {
	/** 
     * 常見的方法列表 
     * @see AtomicInteger#get()             直接返回值 
     * @see AtomicInteger#getAndAdd(int)    增加指定的數據,返回變化前的數據 
     * @see AtomicInteger#getAndDecrement() 減少1,返回減少前的數據 
     * @see AtomicInteger#getAndIncrement() 增加1,返回增加前的數據 
     * @see AtomicInteger#getAndSet(int)    設置指定的數據,返回設置前的數據 
     *  
     * @see AtomicInteger#addAndGet(int)    增加指定的數據後返回增加後的數據 
     * @see AtomicInteger#decrementAndGet() 減少1,返回減少後的值 
     * @see AtomicInteger#incrementAndGet() 增加1,返回增加後的值 
     * @see AtomicInteger#lazySet(int)      僅僅當get時纔會set 
     *  
     * @see AtomicInteger#compareAndSet(int, int) 嘗試新增後對比,若增加成功則返回true否則返回false 
     */  
    public final static AtomicInteger TEST_INTEGER = new AtomicInteger(1);

    public static void main(String[] args) throws InterruptedException {
        final Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            final int num = i;
            threads[i] = new Thread() {
                public void run() {
                    try {
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    int now = TEST_INTEGER.incrementAndGet();
                    System.out.println("我是線程:" + num + ",我得到值了,增加後的值爲:" + now);
                }
            };
            threads[i].start();
        }
        for (Thread t : threads) {
            t.join();
        }
        System.out.println("最終運行結果:" + TEST_INTEGER.get());
    }
}
原子變量的學習!
6.一個餐廳提供5個座位供人吃飯,爲招攬生意同時還提供了免費的雞蛋湯。客人不停的進餐廳吃飯。飯費隨機,湯量隨機。設盛雞蛋湯的木桶容量(capacity)爲100, 當顧客把湯都喝光的時候, 服務員需要去換新的湯桶. 換湯過程中不能再放新人進來。餐廳每天只服務100個顧客,之後停業。
代碼:
people類:
import java.util.Random;

// 顧客
class People implements Runnable {
	public Restaurant dining;
	public String name;

	public People(String name, Restaurant t) {
		this.dining = t;
		this.name = name;
	}

	public void run() {
		System.out.println("顧客[" + name + "] 開始吃飯...");
		try {
			Thread.sleep(new Random().nextInt(500));
		} catch (InterruptedException e) {
		}

		dining.eat(name, new Random().nextInt(11));
		dining.peopleOut(name);
	}
}
Restaurant類:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Restaurant {
	public volatile boolean cleaning = false;
	public volatile int volume = 0;
	public final int CAPACITY = 100;
	public volatile int peopleIn = 0;
	public volatile int count = 0;
	public Waiter cleaner;
	private ExecutorService place = Executors.newFixedThreadPool(5); // 提供 5
																		// 個座位
	public Restaurant() {
		this.cleaner = new Waiter(this);
	}

	public synchronized boolean allowIn(Runnable people) {
		// 餐廳如果滿員,則等待
		while (this.cleaning == true || this.peopleIn >= 5) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		// 每天僅接待 100 名顧客.
		if (count > 100) {
			this.place.shutdown();
			return false;
		} else {
			this.peopleIn(((People) people).name);
			place.submit(people);
			return true;
		}
	}

	public synchronized void eat(String name, int v) {
		this.volume += v;
		System.out.println("顧客[" + name + "] 喝掉 [" + v + "] 湯. 湯桶目前總需求量爲 ["
				+ volume + "]");

		// If the volume exceeds capacity, notify cleaner to clean.
		if (this.volume > this.CAPACITY) {
			this.notifyCleaner();
		}
	}

	public void notifyCleaner() {
		if (this.cleaning == false) {
			System.out.println("湯桶不足 [" + volume + "]. 通知服務員更換湯桶.");
			place.submit(cleaner);
		}
	}

	public synchronized void peopleIn(String name) {
		System.out.println("顧客[" + name + "] 進入餐廳.");
		this.peopleIn++;
		this.count++;
	}

	public synchronized void peopleOut(String name) {
		System.out.println("顧客[" + name + "] 離開餐廳.");
		this.peopleIn--;
		this.notifyAll();
	}

	public synchronized void cleaning() {
		this.cleaning = true;

	}

	public synchronized void cleaned() {
		this.cleaning = false;
		this.notifyAll();
	}
}
Waiter類:
// 服務員換湯.
// 服務員換湯.
class Waiter implements Runnable {
	private Restaurant dining;

	public Waiter(Restaurant t) {
		this.dining = t;
	}

	public void run() {
		dining.cleaning();
		System.out.println("餐廳更換湯桶中...");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
		}
		this.dining.volume = 0;
		System.out.println("餐廳更換湯桶完畢.");
		dining.cleaning = false;
		dining.cleaned();
	}
}
測試類:
public class Test {
	private void test() {
		Restaurant r = new Restaurant();
		boolean allowed = true;
		for (int i = 0; allowed; i++) {
			People p = new People(i + "", r);
			allowed = r.allowIn(p);
		}
	}

	public static void main(String[] args) {
		new Test().test();
	}
}
總結:
     以上所有題目都是公司前輩分享的題目,代碼自然前輩所寫!在學習的過程中,很是很佩服前輩的功底的,向前輩學習! 大笑微笑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章