javaSE21/10/7

多线程

死锁

  • 多个线程互相持有对方需要的资源,然后形成僵持
public class DeadLock {
    public static void main(String[] args) {
        Makeup makeup = new Makeup(0,"莉莉");
        Makeup makeup1 = new Makeup(1,"红红");
        makeup.start();
        makeup1.start();
    }

}
class Lipstick{//口红
}
class Mirror{//镜子
}
class Makeup extends Thread{
    //需要的资源只有一份,用static保证
    static Lipstick l = new Lipstick();
    static Mirror m = new Mirror();
    int choice;
    String girlNmae;
    public Makeup(int choice,String girlNmae){
        this.choice=choice;
        this.girlNmae=girlNmae;
    }
    @Override
    public void run() {
        makeUp();
    }
    private void makeUp(){
        //化妆:互相持有对方的锁,即需要拿到对方的资源
        if (choice==0){
            synchronized (l){//获得口红的锁
                System.out.println(this.girlNmae+"获得口红的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            //一个对象先将拿到的锁释放再拿别的对象的锁,就不会出现死锁
            synchronized (m){//一秒后再获得镜子的锁
                System.out.println(this.girlNmae+"获得镜子的锁");
            }
        }else{
            synchronized (m){//获得镜子的锁
                System.out.println(this.girlNmae+"获得镜子的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            //一个对象先将拿到的锁释放再拿别的对象的锁,就不会出现死锁
            }
            synchronized (l){//一秒后获得口红的锁
                System.out.println(this.girlNmae+"获得口红的锁");
            }
        }
    }
}

Lock

  • 更强大的线程同步机制——通过显示定义同步锁随想来实现同步。用Lock对象
  • Lock是显式锁(手动开锁和关锁),synchronized是隐式锁,出了作用域自动释放
  • Lock是有代码块锁,synchronized有代码块锁和方法锁
  • ReentrantLock可重复所,是Lock的子类

火车票问题Lock解决

public class TestLock {
    public static void main(String[] args) {
        TestLock2 testLock2 = new TestLock2();
        new Thread(testLock2,"张三").start();
        new Thread(testLock2,"李四").start();
        new Thread(testLock2,"王五").start();
    }


}
class TestLock2 implements Runnable{
    int trictNums = 10;
    //定义Lock锁
    private final ReentrantLock lock = new ReentrantLock();//点定义一个可重复锁
    boolean flag = true;
    @Override
    public void run() {
        while (flag){

            try {
                lock.lock();//加锁
                if (trictNums<=0){
                    flag=false;
                    System.out.println("您手慢了");
                    return;
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"您抢到了第"+trictNums--+"张票");
            } finally {
                //解锁
                lock.unlock();
            }

        }

    }
}

生产者消费者问题

public class TestPC {
    public static void main(String[] args) {
        WorkShop container = new WorkShop();
        new Producer(container).start();
        new Consumer(container).start();
    }
}
class Producer extends Thread{//生产者
    WorkShop container;
    public Producer(WorkShop container){
        this.container=container;
    }
    //生产
    @Override
    public void run() {
        for (int i = 1; i < 10; i++) {
            container.push(new Chicken(i));
            System.out.println("生产了"+i+"只鸡");
        }
    }
}
class Consumer extends Thread{//消费者
    WorkShop container;
    public Consumer(WorkShop container){
        this.container=container;
    }

    @Override
    public void run() {
        for (int i = 1; i < 10; i++) {
            System.out.println("消费了"+container.pop().id+"只鸡");
        }
    }
} 
class Chicken{//商品
    int id;//产品号

    public Chicken(int id) {
        this.id = id;
    }
}
class WorkShop{//车间
    //需要一个容器大小
    Chicken[] chickens = new Chicken[10];//定义Chicken类型的数组,所以数组里只能加入Chicken对象
    int count = 0;
    //生产者放入产品
    public synchronized void push(Chicken chicken){
        //如果容器满了,就需要等待消费者消费
        if (count==chickens.length){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //如果没满,就需要丢入产品
        chickens[count]=chicken;//将count索引位置放入商品
        count++;
        //通知消费者消费
        this.notifyAll();
    }
    //消费者消费产品
    public synchronized Chicken pop(){
        //判断能否消费
        if (count==0) {
            //生产者生产,消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //可以消费
        count--;
        Chicken chicken = chickens[count];
        //吃完了,通知生产者生产
        this.notifyAll();
        return chicken;
    }
}
posted @ 2021-10-07 20:49  想吃坚果  阅读(32)  评论(0)    收藏  举报