多线程中的单例

来源:互联网 发布:网络诈骗怎么报警呢 编辑:程序博客网 时间:2024/06/06 09:08


1.通过wait/notify来实现的一个阻塞式队列

package com.wpx.thread.demo02;import java.util.LinkedList;import java.util.concurrent.atomic.AtomicInteger;/** * wait/notif模拟阻塞队列BlockingQueue * 一个特定容器,如果满了需要等待再添加,如果空了,需要有新加入后再取 * 对应两个方法put take  * 新添加的Obj为1新添加的Obj为2新添加的Obj为3新添加的Obj为4新添加的Obj为5 55移除的元素为  1新添加的Obj为6新添加的Obj为75移除的元素为  2 * * @author wangpx */public class demo07 {private LinkedList<Object> list=new LinkedList<>();AtomicInteger count=new AtomicInteger(0);private int minSize = 0;private final   int maxSize ;public demo07(int  maxSize) {this.maxSize=maxSize;}private final Object lock=new Object();public  void putObj(Object obj) {synchronized (lock) {while( count.get() == maxSize) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.add(obj);count.incrementAndGet();System.out.println("新添加的Obj为"+obj);lock.notify();}}public Object takeObj() {Object result=null;synchronized (lock) {while( count.get() == minSize) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}result=list.removeFirst();count.decrementAndGet();lock.notify();}return result; }public int getSize() {return this.count.get();}public static void main(String[] args) {/** * 顺便说一下线程中使用的变量要加final  * 前面也有加,这里不加也没有问题 * 因为jdk1.8可以隐式声明为final * 其实还是相当于final修饰的 */demo07 d=new demo07(5);d.putObj("1");d.putObj("2");d.putObj("3");d.putObj("4");d.putObj("5 ");System.out.println(d.getSize() );Thread t1=new Thread( () ->{System.out.println(d.getSize());d.putObj(6);d.putObj(7);System.out.println(d.getSize());},"t1" );t1.start();Thread  t2=new Thread( () -> {Object obj=d.takeObj();System.out.println("移除的元素为  "+obj);Object obj2=d.takeObj();System.out.println("移除的元素为  "+obj2);},"t2");try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}t2.start();}}

2.关于本地线程

package com.wpx.thread.demo03;/** * ThreadLocal * 线程局部变量,是一种多线程间并发访问变量的解决方案,与synchronized等锁的方式不同 * ThreadLocal完全不提供锁,而使用空间换时间的手段,为每个线程提供变量的独立脚本,以保障线程的安全 * 从性能上讲,ThreadLocal不具有绝对的优势,在并发不是很高的时候,加锁的性能会更好 * 但ThreadLocal可以在一定程度上减少锁竞争 * @author wangpx */public class demo01 {/** * 线程本地绑定    t1 : wpxt2 : null */private static ThreadLocal<String> th =new ThreadLocal<>();public void setTh(String value) {th.set(value);}public void getTh() {System.out.println(Thread.currentThread().getName()+" : "+this.th.get());}public static void main(String[] args) {demo01 d=new demo01();Thread t1=new Thread( () -> {d.setTh("wpx");d.getTh();},"t1");Thread t2=new Thread( () ->  {try {Thread.sleep(1000);d.getTh();} catch (InterruptedException e) {e.printStackTrace();}},"t2");t1.start();t2.start();}}

3.多线程中的单例---静态内部类

package com.wpx.thread.demo03;/** * 单例模式最常见的就是懒汉式和饿汉式对 * 在多线程中,考虑到性能和线程安全问题 * 一般选用 * *      1282066953128206695312820669531282066953128206695312820669531282066953128206695312820669531282066953 * static inner class * @author wangpx */public class demo02 {/** * static inner class * @author wangpx */private static class Singleton{private static Singleton single=new Singleton();}private static Singleton getSingle(){return Singleton.single;}public static void main(String[] args) {Thread[] threads =new Thread[10];int size=threads.length;for (int i=0;i<size;i++) {threads[i]=new Thread(()-> System.out.println(demo02.getSingle().hashCode()));}for(int i=0;i<size;i++ ) {threads[i].start();}}}
4.多线程中的单例---双重校验

package com.wpx.thread.demo03;/** *  dubble check instance *  1386313329138631332913863133291386313329138631332913863133291386313329138631332913863133291386313329 *   * @author wangpx */public class demo03 {private static demo03 d;public static demo03 getDubbleCheck() {if(d==null) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (demo03.class) {if( d == null) {d = new demo03();}}}return d;}public static void main(String[] args) {Thread[] threads =new Thread[10];int size=threads.length;for (int i=0;i<size;i++) {threads[i]=new Thread(()-> System.out.println(d.getDubbleCheck().hashCode()));}for(int i=0;i<size;i++ ) {threads[i].start();}}}