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();
	}
}