JUC概述
1.JUC:并发多线程
是什么? Java.util.concurrent
包括三个包:
Java.util.concurrent
Java.util.concurrent.atomic
Java.util.concurrent.locks
进程/线程
并发/并行
高并发多个线程同一时间点抢同一份资源,比如秒杀
并行几件事同时进行
三个线程并发(三个售票员 卖出 30张票)
如何编写企业级的多线程代码
固定的编程套路+模板是什么?
1.在高内聚低耦合的前提下,线程 操作 资源类
1.1 先创建一个资源类(资源类=实例变量+实例方法)
高内聚:资源类把方法内聚在本身,对外提供接口(举例空调出厂就有制冷制热功能),Java一切皆对象;
低耦合:不依赖别的
在java8的API中找Lock,是接口,提供代码模板如下
Lock l = …;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
实现类举例: java.util.concurrent.locks.ReentrantLock
ReentrantLock可重入不公平递归锁
大量重复代码可以设置到模板里,live templates,如果不会设置可以参考IDEA.
package com.magic.juc0117;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Ticket //资源类 = 实例变量+实例方法
{
private int number = 30;
// synchronized 全锁 粒度大 这里采用Lock
Lock lock = new ReentrantLock();
public void sale(){
lock.lock();
try{
if(number > 0){
System.out.println(Thread.currentThread().getName()+"\t卖出第:"+(number--)+"\t 还剩下"+number+"张");
}
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* @Description 完成目标,算是OK,但是可以更好
* @Author Chelsea
* @Date 2020/1/17 13:00
*/
public class SaleTicketDemo01 {
/**
* 题目:三个售票员 卖出 30张票
* 目标:如何编写企业级的多线程代码
* 固定的编程套路+模板是什么?
* 1.在高内聚低耦合的前提下,线程 操作 资源类
* 1.1 先创建一个资源类
*/
public static void main(String[] args) {//主线程,触发入口
final Ticket ticket = new Ticket();
// 以lambda表达式完成
new Thread(() -> {
for (int i = 0; i <= 40 ; i++) {
ticket.sale();
}
},"A").start();
new Thread(() -> {
for (int i = 0; i <= 40 ; i++) {
ticket.sale();
}
},"B").start();
new Thread(() -> {
for (int i = 0; i <= 40 ; i++) {
ticket.sale();
}
},"C").start();
//下面注释掉的是普通完成方式 java8以前 完成目标,算是OK,但是可以更好,所以用了上面的lambda表达式
// Thread(Runnable target, String name) 分配一个新的 Thread对象。
//接口可以new 匿名内部类 Java8
// new Thread(new Runnable() {
// public void run() {
// for (int i = 0; i <= 40 ; i++) {
// ticket.sale();
// }
// }
// }, "A").start();//就绪状态
// new Thread(new Runnable() {
// public void run() {
// for (int i = 0; i <= 40 ; i++) {
// ticket.sale();
// }
// }
// }, "B").start();
//
// new Thread(new Runnable() {
// public void run() {
// for (int i = 0; i <= 40 ; i++) {
// ticket.sale();
// }
// }
// }, "C").start();
}
}
lambda表达式及函数式接口
package com.magic.juc0117;
/**
* @Description
*
* 函数式编程
*
* @Author Chelsea
* @Date 2020/1/17 16:32
*/
@FunctionalInterface
interface Foo
{
// public void sayHello();
public int add(int x,int y);
public default int mul(int x ,int y){
return x*y;
}
public static int dd(int x ,int y){
return x*y;
}
public static int dd1(int x ,int y){
return x*y;
}
}
public class LambdaExpressDemo02 {
public static void main(String[] args) {
//注释掉的是匿名内部类的写法
// Foo foo = new Foo() {
// @Override
// public void sayHello() {
// System.out.println("***hello");
// }
// };
// foo.sayHello();
/**1.拷贝小括号,写死右箭头,落地大括号 解决了匿名内部类的代码冗余
* 2.@FunctionalInterface 函数式接口要求有且仅有一个方法(不然会报错),
* 可以有多个default、static方法,如果没有这个注解,只有一个方法则Java8底层会隐式加上
* 3.default方法可以有多个,有方法体
* 4.static 方法可以有多个
*/
// Foo foo = ()->{
// System.out.println("lambda hello");
// };
// foo.sayHello();
Foo foo = (int x,int y)->{
System.out.println("lambda add");
return x+y;
};
int result = foo.add(2,3);
System.out.println("result"+result);
}
}
学习整理于JUC.