ReentrantLock可重入锁

多线程企业级Demo

  1. 前提

    所有的多线程开开发遵循一个规则:

    在高内聚低耦合的前提下,线程-->操作-->资源类

    在这个条件下我们写一个卖票的Demo,三个售票员卖出30张票

  2. 资源类

    //资源类
    class Ticket {
    //创建一个可重入的lock锁
    Lock lock = new ReentrantLock();
    //总30张票
    private int number = 30;

    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(); //解锁
    }
    }
    }
  3. 线程

    new Thread(new Runnable() {
    @Override
    public void run() {
    for (int i = 0; i < 40; i++) {
    //待操作的代码
    }
    }
    },"a").start();

    注意: 我们查看Runnable()接口的源代码发现,这是一个函数式接口,下面提供源码

    @FunctionalInterface
    public interface Runnable {
    public abstract void run();
    }

    所以我们可以使用lambda表达式简化操作

  4. 操作

    //new资源类
    Ticket ticket = new Ticket();
    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();
  5. 结果:

    A卖票员	卖出第30	张票,还剩下29
    A卖票员 卖出第29 张票,还剩下28
    A卖票员 卖出第28 张票,还剩下27
    ...
    A卖票员 卖出第1 张票,还剩下0

Lambda表达式与函数式接口

在jdk1.8中,引入了函数式接口,函数式接口中只能声明一个抽象方法,lambda表达式可以直接使用这个接口

  1. 定义函数式接口

    @FunctionalInterface	//显式指定 当接口中只有一条抽象方法时,默认是函数式接口
    interface Foo {
    public void sayHello();
    }
  2. 使用lambda表达式实现

    public static void main(String[] args) {
    //指定接口的实现
    Foo foo = () -> System.out.println("hello FunctionInterface..");
    foo.sayHello();
    }

还需要知道的是在jdk1.8中,引入了default方法修饰接口,并且可以在接口中声明static方法,但是必须实现方法,这里和我们印象中的java接口有点不同

//@FunctionalInterface  //声明函数式接口 只有一条抽象方法时可以省略
interface Foo {
//声明抽象方法
public void sayHello();

//声明默认方法
public default int add(int x,int y){
return x+y;
}
//声明静态方法
public static int dec(int x,int y){
return x-y;
}
}

//定义类,没有实现接口
public class FuncitonInterfaceDemo {
public static void main(String[] args) {
//Foo对象接收实现的接口
Foo foo = () -> System.out.println("hello FunctionInterface..");
foo.sayHello();

//Foo对象的引用调用add方法
System.out.println(foo.add(10, 5));

//接口名直接调用static修饰的dec方法
System.out.println(Foo.dec(10, 5));
};
}
Author: Tunan
Link: http://yerias.github.io/2019/01/01/java/1/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.