Java知识点JUC总结

时间:2020-07-11 19:29:37   收藏:0   阅读:70

JUC:java.util.concurrent (Java并发编程工具类)

java.util.concurrent.locks

多线程8锁:

	public static synchronized void sendEmail() throws Exception {
		try{ TimeUnit.SECONDS.sleep( 4 ); } catch(InterruptedException e) {e.printStackTrace();}
		System.out.println("sendEmai.."); // 打印邮件
	}
	public static synchronized void sendSMS() throws Exception {
		System.out.println("sendSMS.."); // 打印短信
	}
	public void hello() {
		System.out.println("hello..");
	}

List 线程不安全

Callable接口

CountDownLatch:可以控制多线程的main线程最后执行,countDownLatch.countDown();做的减法

		CountDownLatch countDownLatch = new CountDownLatch(6); // 信号数为6
		for(int i = 1; i <= 6; i++){
			new Thread(() -> {
				System.out.println(Thread.currentThread().getName()+"\t离开教室");
				countDownLatch.countDown(); // 倒计信号数,执行一次减一
			}, String.valueOf(i)).start();
		}
		countDownLatch.await();  // 堵住该main线程直到除main外的其他线程结束后才放行
		System.out.println(Thread.currentThread().getName()+"\t班长关门走人"); // 信号数减到0时才执行main线程

CyclicBarrier:可以控制多线程的main线程最后执行,和 CountDownLatch 不同的是CyclicBarrier做的加法

CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {System.out.println("召唤神龙");});  //设置信号数
		for (int i = 1; i <= 7; i++) {
			final int tempInt = i;
			new Thread(() -> {
				System.out.println(Thread.currentThread().getName()+"\t收集到第:"+tempInt+"颗龙珠");
				try {
					cyclicBarrier.await();
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}, String.valueOf(i)).start(); // 信号数加到7时才执行main线程
		}



Semaphore: 设置信号量,用于多个共享资源的互斥使用,还用于并发线程数的控制,限流

public static void main(String[] args) {
		// 模拟资源类,有3个空车位, 当一个线程占用资源后减少一个空车位,应用场景:抢红包
		Semaphore semaphore = new Semaphore(3); // 3是设置的信号量,用于多个共享资源的互斥使用,还用于并发线程数的控制,限流
		for(int i = 1; i <= 6; i++){
			new Thread(() -> {
				try {
					semaphore.acquire();
					System.out.println(Thread.currentThread().getName()+"\t抢占到了车位");
					try{TimeUnit.SECONDS.sleep(3);}catch (Exception e) {e.printStackTrace();}
					System.out.println(Thread.currentThread().getName()+"\t离开了车位");
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					semaphore.release(); // 释放资源
				}
			}, String.valueOf(i)).start();
		}
	}

ReadWriteLock读写锁:写时排它,锁控制数据一致性。唯一写,并发读

	public void put(String key, Object value){
		readWriteLock.writeLock().lock();
		try {
			System.out.println(Thread.currentThread().getName()+"\t 开始写入");
			map.put(key, value);
			System.out.println(Thread.currentThread().getName()+"\t 写入完成");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally{
			readWriteLock.writeLock().unlock();
		}
	}

阻塞队列BlockingQueue接口

技术图片

技术图片

ThreadPool 线程池

技术图片

public static void main(String[] args) {
		System.out.println(Runtime.getRuntime().availableProcessors()); // 获取计算机内核数
		ExecutorService threadPool = new ThreadPoolExecutor(
				2, 
				5,   // 如果得到的内核数是CPU密集型,就比核数多1~2
				2L, 
				TimeUnit.SECONDS, 
				new LinkedBlockingDeque<>(3),
				Executors.defaultThreadFactory(), 
				new ThreadPoolExecutor.AbortPolicy());
		try {
			for (int i = 0; i <= 10; i++) {
				threadPool.execute(() -> { // Runnable 可用Lambda表达式
					System.out.println(Thread.currentThread().getName()+"\t办理业务");
				});
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

技术图片

? 一般使用以下方法创建线程池, 此时线程池最大容纳数是5+3, 最大线程数是5

ExecutorService threadPool = new ThreadPoolExecutor(2, 5, 2L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(3), 		             		             		          		          Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

技术图片

Java.util.function(四大函数式接口):

技术图片

Stream流式计算

public static void main(String[] args) {  // stream式计算
		User u1 = new User(11, "a", 23);
		User u2 = new User(12, "b", 24);
		User u3 = new User(13, "c", 22);
		User u4 = new User(14, "d", 28);
		User u5 = new User(16, "e", 26);
		List<User> list = Arrays.asList(u1,u2,u3,u4,u5); 
		// 形参 u 代表 List<User>的泛型User
		list.stream().filter(u -> {return u.getId() % 2 == 0;}) // 选取偶数id
		.filter(u -> {return u.getAge() > 24;})	// 选取 age 大于 24
		.map(m -> {return m.getUserName().toUpperCase();}) // list转为map,名字变为大写
		.sorted((o1,o2) -> {return o2.compareTo(o1);}).limit(1) // 逆序,输出第一个对象
		.forEach(System.out::println);   	// 遍历输出E
	}

分支合并框架

抽象类不能直接通过new而实例化,需要创建一个指向自己的对象引用(其子类)来实例化

异步回调

public class CompletableFutureDemo {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
			System.out.println(Thread.currentThread().getName() + "\t没有返回, update mysql ok");
		});
		completableFuture.get();
		
		// 异步回调
		CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {
			System.out.println(Thread.currentThread().getName() + "\tcompletableFuture2");
//			int age = 10/0;
			return 1024;
		});
		System.out.println(completableFuture2.whenComplete((t, u) -> { // 正常时返回 completableFuture2 的返回值
			System.out.println("*****t:" + t);  // t 为 completableFuture2  异步回调的返回值
			System.out.println("*****u:" + u);	// u 为 completableFuture2 异步回调的异常信息
		}).exceptionally(f -> {   // 异常时返回 completableFuture2 的异常
			System.out.println("*****exception:" + f.getMessage());
			return 444;
		}).get()); // 打印返回值结果
	}
}
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!