口碑好的南昌网站建设,小红书推广文案怎么写,装修设计网站哪个最好,上海备案证查询网站查询系统单列模式 单例模式能保证某个类在程序中只存在唯⼀⼀份实例, ⽽不会创建出多个实例 1.饿汉模式 只要程序一启动就会立即创建出一个对象
class Signleton{private static Signleton instancenew Signleton();//防止在以后的代码中再创建对象#xff0c;我们将构造方法private,…单列模式 单例模式能保证某个类在程序中只存在唯⼀⼀份实例, ⽽不会创建出多个实例 1.饿汉模式 只要程序一启动就会立即创建出一个对象
class Signleton{private static Signleton instancenew Signleton();//防止在以后的代码中再创建对象我们将构造方法private,private Signleton(){}public static Signleton getInstance(){return instance;}
}注意虽然构造方法是private但是我们仍然可以在类外面用反射拿到私有构造方法创建实例 如果在代码中存在多个单例类饿汉模式在程序启动的时候就会发生扎堆创建延缓了程序启动时间。
2.懒汉模式 只有在调用的时候才会创建对象
class SingletonLazy {private static volatile SingletonLazy instancenull;private SingletonLazy(){}public static void getInstance(){if(instancenull){synchronized (SingletonLazy.class){if(instancenull){instancenew SingletonLazy();}}}}}懒汉模式进阶
class Singleton {
//在这里我们加入volatile第一点为了内存可见性问题第二点为了指令重排序问题private static volatile Singleton instance null;private Singleton() {}public static Singleton getInstance() {if (instance null) {synchronized (Singleton.class) {if (instance null) {instance new Singleton();}}}return instance;}
}假设有两个线程t1t2.线程之间是强占是执行的t1t2都通过第一层判断instancenull假设t1拿到锁在t1执行完返回一个instance这是instance不再是null所以在t1线程释放锁后t2线程将不再进入第二层的判断故这个对象只创建了一次。这种双重if就避免了重复创建对象
指令重排序问题 此程序代码大体可以三个步骤 1.申请内存空间 2.调用构造方法 3.把此时内存空间的地址幅值给instance引用
如上图在t1和t2线程中如果在t1线程执行了第一步和第二步没有把第三步执行完就去执行线程t2此时instance这个引用已经不为空了也就是说返回创建的对象根本就没有创建好。
阻塞队列 在 Java 标准库中内置了阻塞队列. 如果我们需要在⼀些程序中使⽤阻塞队列, 直接使⽤标准库中的即 阻塞队列相比较于普通队列和优先级队列来说线程是安全的而其他两个线程是不安全的
BlockingQueue 是⼀个接⼝. 真正实现的类LinkedBlockingQueue.put ⽅法⽤于阻塞式的⼊队列, take ⽤于阻塞式的出队列.BlockingQueue 也有 offer, poll, peek 等⽅法, 但是这些⽅法不带有阻塞特性.可.
BlockingQueueString queue new LinkedBlockingQueue();
// ⼊队列
queue.put(abc);
// 出队列. 如果没有 put 直接 take, 就会阻塞.
String elem queue.take();这种就阻塞了
public class demo2 {public static void main(String[] args) throws InterruptedException {BlockingQueueString queuenew ArrayBlockingQueue(1000);queue.put(aaa);String elem queue.take();System.out.println(elemelem);queue.take();}
}用阻塞队列实现消费者模型 public static void main(String[] args) throws InterruptedException {BlockingQueueInteger blockingQueuenew LinkedBlockingQueue();Thread customnew Thread(()-{while (true){try {int value blockingQueue.take();System.out.println(消费者value);} catch (InterruptedException e) {throw new RuntimeException(e);}}},消费者);custom.start();Thread producernew Thread(()-{Random randomnew Random();while (true){try {int numrandom.nextInt(1000);blockingQueue.put(num);System.out.println(生产者num);Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},生产者);producer.start();custom.join();producer.join();}
}消费者模型有很多优势其中两个最重要的是 1.解耦合线程只关心与队列的交互不用管线程之间的交互 2.削峰填谷大概意思就是假如是两个线程这两个线程相互制约以最慢的为准你生产一个我去消费一个