0
点赞
收藏
分享

微信扫一扫

多线程案例【一】

爱写作的小土豆 2022-03-30 阅读 56
java-ee

目录

多线程案例

单例模式

单例模式是一种设计模式。
写代码时有些常见场景,设计模式就是针对这些常见场景给出的解决方案。

饿汉模式

class Singleton{
    //1.使用static创建一个实例,并且立即进行实例化
    //这个instance对应的实例,就是该类的唯一实例
     private static Singleton  instance=new Singleton();
     //2.为了防止程序员在其他地方不小心new这个singleton,就可以把构造方法设为private
    private Singleton(){}
    //3.提供一个方法,让外面的能够拿到唯一的实例
    public static Singleton getInstance(){
        return  instance;
    }
}
public class Demo19 {
    public static void main(String[] args) {
        Singleton instance=Singleton.getInstance();
    }

}

懒汉模式【经典面试题】

在这里插入图片描述

那么懒汉模式怎样保证线程安全呢?

public static Singleton2 getInstance(){
        //并不是代码中有synchronized就一定线程安全,synchronized加的位置也得正确
        //使用类对象作为锁对象(类对象在一个程序中,只有唯一的一份,就能保障多个线程调用getInstance的时候就是针对同一个对象进行加锁的)

        //如果这个条件成立,说明当前的单例模式未初始化,存在线程安全风险,就需要加锁
        if(instance ==null){
            synchronized (Singleton2.class){
                if(instance==null){
                    instance= new Singleton2();
                }
            }
        }

        return instance;
    }

最终的代码:

class Singleton2{
    //1.懒汉模式就不是立即初始化实例
    private static  volatile  Singleton2 instance=null;

    //2.把构造方法设为private
    private Singleton2(){}
    //3.提供一个方法来获取到上述单例的实例
    //只有当真正用到这个实例的时候,才会真正去创建这个实例
    public static Singleton2 getInstance(){
        //并不是代码中有synchronized就一定线程安全,synchronized加的位置也得正确
        //使用类对象作为锁对象(类对象在一个程序中,只有唯一的一份,就能保障多个线程调用getInstance的时候就是针对同一个对象进行加锁的)

        //如果这个条件成立,说明当前的单例模式未初始化,存在线程安全风险,就需要加锁
        if(instance ==null){
            synchronized (Singleton2.class){
                if(instance==null){
                    instance= new Singleton2();
                }
            }
        }

        return instance;
    }

}

public class Demo20 {
    public static void main(String[] args) {
        Singleton2 instance =Singleton2.getInstance();
    }
}

阻塞队列

此时的阻塞队列就可以作为生产者消费者模型中的交易场所

在这里插入图片描述

java标准库中阻塞队列的用法

public class Demo21 {
    public static void main(String[] args) throws InterruptedException {
        BlockingDeque<String > queue=new LinkedBlockingDeque<>();
        queue.put("hello");
        String s=queue.take();
    }
}

自己实现阻塞队列

在这里插入图片描述
在这里插入图片描述

class  MyBlockingQueue{
    //保存数据本体
    private int[] data=new int[100];
    //有效元素个数
    private int size=0;
    //队首下标
    private int head=0;
    //队尾下标
    private int tail=0;
    //专门的锁对象
    private Object locker=new Object();

    //入队
    //对于put操作,阻塞条件是队列为满
    public  void put(int value) throws InterruptedException {
        synchronized (locker){
            if(size==data.length){
                locker.wait();
            }
            data[tail]=value;
            tail++;
            if(tail >= data.length){
                tail=0; // tail=tail % data.length
            }
            size++;
            //如果入队列成功,则队列非空,于是就唤醒take中的阻塞等待
            locker.notify();
        }

    }


        //出队列
    public Integer take() throws InterruptedException {
        synchronized (locker){
            if(size==0){
                //如果队列为空,就返回一个一个非法值
               // return null;
                locker.wait();
            }
            int ret=data[head];
            head++;
            if(head >= data.length){
                head=0;
            }
            size--;
            //take 成功之后,就唤醒put中的等待
            locker.notify();
            return  ret;

        }
    }
}


public class Demo22 {
    private static MyBlockingQueue queue=new MyBlockingQueue();
    public static void main(String[] args) {
        //实现一个简单的生产者消费者模型
        Thread producer=new Thread(() ->{
            int num=0;
            while(true){
                try {
                    System.out.println("生产了:"+ num);
                    queue.put(num);
                    num++;
                    //当生产者生产的慢一些的时候,消费者就得跟着生产者的步伐走
                    //Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        producer.start();

        Thread customer =new Thread(() ->{
            while(true){
                try {
                    int num=queue.take();
                    System.out.println("消费了:"+num);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        customer.start();






    }
}

举报

相关推荐

0 条评论