3、JUC系列之---Concurrent

若如初见. 提交于 2020-02-29 17:04:57

一、卖票

需求:三个人卖30张票

代码:

package com.lee.juc.concurrent;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SaleTicket {

	public static void main(String[] args) {
		
		Ticket ticket = new Ticket();
		
		new Thread(new Runnable() {
			public void run() {
				for(int i=0;i<100;i++) {
					ticket.sale();
				}
			}
		},"AA").start();
		
		new Thread(new Runnable() {
			public void run() {
				for(int i=0;i<100;i++) {
					ticket.sale();
				}
			}
		},"BB").start();
		
		new Thread(new Runnable() {
			public void run() {
				for(int i=0;i<100;i++) {
					ticket.sale();
				}
			}
		},"CC").start();
		
	}
}

//票
class Ticket{
	
	private int num=30;
	private Lock lock = new ReentrantLock();
	
	public void sale() {
		lock.lock();
		try {
			if(num>0) {
				System.out.println(Thread.currentThread().getName()+".....sale ticket number : "+num--);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
}

用lambda写:

package com.lee.juc.concurrent;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SaleTicket {

	public static void main(String[] args) {
		
		Ticket ticket = new Ticket();
		
		new Thread(()->{for(int i=0;i<100;i++) {ticket.sale();}},"AA").start();
		new Thread(()->{for(int i=0;i<100;i++) {ticket.sale();}},"BB").start();
		new Thread(()->{for(int i=0;i<100;i++) {ticket.sale();}},"CC").start();
		
	}
}

//票
class Ticket{
	
	private int num=30;
	private Lock lock = new ReentrantLock();
	
	public void sale() {
		lock.lock();
		try {
			if(num>0) {
				System.out.println(Thread.currentThread().getName()+".....sale ticket number : "+num--);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
}

二、Callable

代码:

package com.lee.juc.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
 * 在主线程中需要执行比较耗时的操作,但又不想阻塞主线程时.可以把这些对象交给Future对象在后台执行,当主线程需要时,
 * 就可以通过Future对象获得后台作业计算的结果或者执行状态.
 * 
 * 一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果.
 * 
 * 仅在计算完成时才能检索结果,如果计算尚未完成,则阻塞get方法.一旦计算完成,就不能再重新开始或取消计算.
 * get方法获取结果只有在计算完成时获取,否则会一直阻塞到任务转入完成状态,然后会返回结果或者抛出异常.
 *
 */
public class CallableDemo {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		FutureTask<Integer> futureTak = new FutureTask<>(new MyThread());
		
		new Thread(futureTak, "AA").start();
		new Thread(futureTak, "BB").start();
		
		System.out.println("...this is main method : "+Thread.currentThread().getName());
		
		Integer aResult = futureTak.get();
		System.out.println("A---->"+aResult);
		
		
		Integer bResult = futureTak.get();
		System.out.println("B---->"+aResult);
		
	}
}

class MyThread implements Callable<Integer>{

	public Integer call() throws Exception {
		System.out.println("this is...call...method : "+Thread.currentThread().getName());
		Thread.sleep(3000);
		return 300;
	}
	
}

三、线程池

代码:

package com.lee.juc.concurrent;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class ExecutorDemo {

	public static void main(String[] args) {
	
		ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
		ScheduledFuture<Integer> scheduledFuture = null;
		try {
			
			for (int i = 0; i < 10; i++) {
				scheduledFuture = scheduledExecutorService.schedule(()->{
					System.out.print(Thread.currentThread().getName()+"...");
					return new Random().nextInt(10);
				}, 2, TimeUnit.SECONDS);
				System.out.println("...."+scheduledFuture.get());
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			scheduledExecutorService.shutdown();
		}
		
		
		
	}
	
	
	

	private static void ExecutorService() {
		//		ExecutorService executorService = Executors.newFixedThreadPool(5);
		//		ExecutorService executorService = Executors.newSingleThreadExecutor();
				ExecutorService executorService = Executors.newCachedThreadPool();
				
				Future<Integer> future = null;
				try {
				
					for(int i=0;i<10;i++) {
						 future = executorService.submit(()->{
							System.out.print(Thread.currentThread().getName()+"...");
							return new Random().nextInt(10);
						 });
						 
						 System.out.println("...."+future.get());
					}
					
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					executorService.shutdown();
				}
	}
	
}


四、CountDownLatch

代码:

package com.lee.juc.concurrent;

public enum CountryEnum {

	ONE(1,"韩"),TWO(2,"赵"),THREE(3,"燕"),FOUR(4,"魏"),FIVE(5,"楚"),SIX(6,"齐");
	
	private Integer code;
	private String message;
	
	
	private CountryEnum(Integer code, String message) {
		this.code = code;
		this.message = message;
	}


	public Integer getCode() {
		return code;
	}


	public void setCode(Integer code) {
		this.code = code;
	}


	public String getMessage() {
		return message;
	}


	public void setMessage(String message) {
		this.message = message;
	}
	
	public static CountryEnum foreachCountryEnums(Integer index) {
		for(CountryEnum countryEnum : values()) {
			if(countryEnum.getCode() == index) {
				return countryEnum;
			}
		}
		return null;
	}


	
	
}

//=================================================================

package com.lee.juc.concurrent;

import java.util.concurrent.CountDownLatch;
/**
 *	让一些线程阻塞直到另一些线程完成后,才被唤醒
 *
 * 	6国被灭后,秦才一统华夏
 */
public class CountDownLatchDemo {

	public static void main(String[] args) throws InterruptedException {
		
		CountDownLatch latch = new CountDownLatch(6);
		
		for (int i = 1; i <= 6; i++) {
			new Thread(()->{
				System.out.println(Thread.currentThread().getName()+"\t国被灭");
				latch.countDown();
			}, CountryEnum.foreachCountryEnums(i).getMessage()).start();
		}
		
		latch.await();
		
		System.out.println(Thread.currentThread().getName()+"....."+"秦灭六国,一统华夏");
		
	}
	
}

五、Semaphore

代码:

package com.lee.juc.concurrent;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
 *	在信号量上我们定义两种操作:
 *		acquire(获取),当一个线程调用acquire操作时,他要么成功通过获取信号量(信号量减1),要么一直等下去,直到有线程释放信号量,或超时.
 *		release(释放),实际上会将信号量的值加1,然后唤醒等待的线程.
 *
 *	信号量主要用于两个目的:
 *		一个是用于共享资源的互斥.
 *		另一个是用于并发线程的控制.
 *
 *	eg:模拟6辆车,抢3个停车位.
 *
 */
public class SemaphoreDemo {

	public static void main(String[] args) {
		Semaphore semaphore = new Semaphore(3);//模拟三个车位
		
		for (int i = 0; i < 6; i++) { //模拟6辆车
			
			try {
				new Thread(()->{
					try {
						semaphore.acquire();//占领车位
						System.out.println(Thread.currentThread().getName()+"  占领车位...");

						TimeUnit.SECONDS.sleep(new Random().nextInt(5));//占领一段时间
						System.out.println("...."+Thread.currentThread().getName()+"离开车位");
						
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						semaphore.release();
					}
				}, String.valueOf(i)).start();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				
			}
			
			
		}
		
	}
}

六、CyclicBarrier

代码:

package com.lee.juc.concurrent;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

/**
 * cyclic可循环的  barrier栅栏、屏障
 * 		让一组线程达到屏障时(阻塞点)被阻塞,直到最后一个线程也达到了屏障时,屏障才会打开,所有被屏障的线程才会继续干活。
 * 		 
 *	eg:集齐七颗龙珠,召唤神龙
 */
public class CyclicBarrierDemo {

	private static final Integer NUMBER = 7;
	public static void main(String[] args) {
		
		CyclicBarrier cyclicBarrier = new CyclicBarrier(7, ()->{System.out.println("召唤神龙!");});
		
		for (int i = 0; i < NUMBER; i++) {
			Integer temp = i;
			new Thread(()->{
				
				try {
					TimeUnit.SECONDS.sleep(new Random().nextInt(5));//手机龙珠的过程
					System.out.println(Thread.currentThread().getName()+"\t收集到第"+temp+"颗龙珠");
					cyclicBarrier.await();//等着其他龙珠被收集
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (BrokenBarrierException e) {
					e.printStackTrace();
				}
				
			},String.valueOf(i)).start();
		}
		
	}
}

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!