单例模式
某个类在整个进程的运行过程中,只允许有一个对象
-
饿汉模式
public class HungryMan { //一开始就初始化 private static HungryMan instance = new HungryMan(); private HungryMan() { } public static HungryMan getInstance() { return instance; } static class MyThread extends Thread { @Override public void run() { HungryMan ins1 = HungryMan.getInstance(); System.out.println(ins1); } } public static void main(String[] args) { //单线程环境下 // singleton.HungryMan ins1 = singleton.HungryMan.getInstance(); // singleton.HungryMan ins2 = singleton.HungryMan.getInstance(); // singleton.HungryMan ins3 = singleton.HungryMan.getInstance(); // // System.out.println(ins1 == ins2); //true // System.out.println(ins2 == ins3); //true //多线程环境下也是同一个对象 MyThread[] threads = new MyThread[20]; for (int i = 0; i < 20; i++) { threads[i] = new MyThread(); } for (int i = 0; i < 20; i++) { threads[i].start(); } } }
-
懒汉模式
public class LazyMan { private static volatile LazyMan instance = null; private LazyMan() { } //单线程版,多线程环境下可能会出现问题 // public static LazyMan getInstance() { // if (instance == null) { // instance = new LazyMan(); // } // return instance; // } //法一二三四都是多线程版 //法一: public static LazyMan getInstance1() { synchronized (LazyMan.class) { if (instance == null) { instance = new LazyMan(); } } return instance; } // //法二: // public synchronized static LazyMan getInstance2() { // if (instance == null) { // instance = new LazyMan(); // } // return instance; // } // // //法三: // private static Object lock = new Object(); //在方法外面 // public static LazyMan getInstance3() { // synchronized (lock) { // if (instance == null) { // instance = new LazyMan(); // } // } // return instance; // } //二次判断-性能高 public static LazyMan getInstance4() { if (instance == null) { synchronized (LazyMan.class) { if (instance == null) { instance = new LazyMan(); //有重排序问题,加入volatile } } } return instance; } static class MyThread extends Thread { @Override public void run() { LazyMan ins = LazyMan.getInstance4(); System.out.println(ins); } } public static void main(String[] args) { // //单线程 // LazyMan ins1 = LazyMan.getInstance(); // LazyMan ins2 = LazyMan.getInstance(); // LazyMan ins3 = LazyMan.getInstance(); // System.out.println(ins1 == ins2); //true // System.out.println(ins2 == ins3); //true //多线程环境下 MyThread[] threads = new MyThread[20]; for (int i = 0; i < 20; i++) { threads[i] = new MyThread(); } for (int i = 0; i < 20; i++) { threads[i].start(); } } }
-
高效的多线程版本
-
为什么synchronized
- 多线程情况下,原子性被破坏
-
为什么二次判断
- getInstance()会被调用很多次,而互斥的情况只在instance==null的时候发生
-
为什么volatile
- instance = new Singleton()有重排序问题
阻塞式队列
-
自己实现
public class MyArrayBlockingQueue { int[] array = new int[10]; int front = 0; //只有消费者会改变 int rear = 0; //只有生产者会改变 int size = 0; //共享且会被修改 synchronized void put(int value) throws InterruptedException { while (size == array.length) { wait(); } array[rear] = value; rear = (rear + 1) % array.length; size++; System.out.println(size); notifyAll(); } synchronized void put2(int value) throws InterruptedException { if (size == array.length) { this.wait(); } array[rear] = value; rear = (rear + 1) % array.length; size++; System.out.println(size); notify(); } synchronized int take() throws InterruptedException { if (size == 0) { this.wait(); } int t = array[front]; front = (front + 1) % array.length; size--; notify(); return t; } static MyArrayBlockingQueue queue = new MyArrayBlockingQueue(); static class Producer extends Thread { @Override public void run() { int j = 0; while (true) { try { queue.put(j); j++; } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws InterruptedException { //多个生产者和多个消费者情况下 MyBlockingArrayQueue.Producer producer1 = new MyBlockingArrayQueue.Producer(); MyBlockingArrayQueue.Producer producer2 = new MyBlockingArrayQueue.Producer(); MyBlockingArrayQueue.Producer producer3 = new MyBlockingArrayQueue.Producer(); producer1.start(); producer2.start(); producer3.start(); Thread.sleep(2*1000); while (true) { queue.take(); } } }
-
使用
public class BlockingQueueDemo { public static void main(String[] args) throws InterruptedException { BlockingQueue<String> q1 = new ArrayBlockingQueue(15); BlockingQueue<String> q2 = new LinkedBlockingDeque<>(); BlockingQueue<String> q3 = new PriorityBlockingQueue<>(); q1.put(""); String take = q1.take(); System.out.println(take); } }
定时器
-
自己实现
import java.util.concurrent.TimeUnit; //定时器,10秒后打印一个happy public class SimpleTimer { interface SimpleTimerTask { void run(); } //这个线程先 sleep delay时间后,再去执行任务 static class Worker extends Thread { long delay; SimpleTimerTask task; Worker(SimpleTimerTask task, long delay) { this.task = task; this.delay = delay; } @Override public void run() { try { Thread.sleep(delay); task.run(); } catch (InterruptedException e) { e.printStackTrace(); } } } void schedule(SimpleTimerTask task, long delay) { Worker worker = new Worker(task, delay); worker.start(); } static class MyTask implements SimpleTimerTask { @Override public void run() { System.out.println("happy"); } } public static void main(String[] args) throws InterruptedException { SimpleTimer timer = new SimpleTimer(); MyTask task = new MyTask(); timer.schedule(task, 10*1000); int i = 0; while (true) { System.out.println(i++); TimeUnit.SECONDS.sleep(1); } } }
-
使用
import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; public class TimerDemo { static class MyTask extends TimerTask { @Override public void run() { System.out.println("已经是 10 秒中后了"); } } public static void main(String[] args) throws InterruptedException { TimerTask task = new MyTask(); Timer timer = new Timer(); timer.schedule(task, 10*1000); int i = 0; while (true) { System.out.println(i++); TimeUnit.SECONDS.sleep(1); } } }