单例中的线程不安全性

来源:互联网 发布:什么是数组 编辑:程序博客网 时间:2024/06/05 11:45

一、单例设计模式(懒汉式)中的线程不安全问题
看之前写过的一个单例

public class SingleTest {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        Single s1 = Single.getInstance();        Single s2 = Single.getInstance();        System.out.println(s1==s2);    }}class Single{    private Single() {    }    private  static Single s = null;    public static Single getInstance(){        if(s==null){            s = new Single();         }        return s;    }} 

在多线程情况下,上面的单例会出现多次判断的问题。如果直接在getInstance()方法前面加上synchronized 则执行效率会比较低,没创建一次,都得判断是否lock住。可以加上双重判断,来减少锁的判断次数。同步锁是该类所属的字节码文件对象。

class Single {    private Single() {    }    private static Single s = null;    public static Single getInstance() {        if (s == null) {            synchronized (Single.class) {                if (s == null) {                    s = new Single();                }            }        }        return s;    }}

二、进程同步问题
问题描述:设有两个线程,一个线程负责写数据(前后两次数据不同,可以设置flag变量来进行input的切换),另一个线程负责读数据。问如何实现同步。

public class InputOutput {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        Resource r = new Resource();        Input in = new Input(r);        Output out = new Output(r);        Thread thread = new Thread(in);        Thread thread1 = new Thread(out);        thread.start();        thread1.start();    }}class Resource{    String name ;    String sex ;} class Input implements Runnable{    Resource s;    Input(Resource s){        this.s= s;    }     public void run(){        boolean flag = true;        while(true){            synchronized(s){            if(flag){                s.name = "张三";                s.sex  =  "男";                flag = false;            }else{                s.name = "丽丽";                s.sex = "女";                flag = true;            }}        }    }}class Output implements Runnable{    Resource s;    Output(Resource s){        this.s = s;    }    public void run(){        while(true){            synchronized(s){        System.out.println(s.name+" "+s.sex);}          }}}

代码优化后:

public class InputOutput {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        Resource r = new Resource();        Input in = new Input(r);        Output out = new Output(r);        Thread thread = new Thread(in);        Thread thread1 = new Thread(out);        thread.start();        thread1.start();    }}class Resource {    private String name;    private String sex;    private boolean flag;    public synchronized void set(String name, String sex) {        if (!flag) {            this.name = name;            this.sex = sex;            flag = true;            this.notify();        }        try {            this.wait();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public synchronized void info() {        if (flag) {            System.out.println(name + "..." + sex);            flag = false;            this.notify();        }        try {            this.wait();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}class Input implements Runnable {    Resource s;    Input(Resource s) {        this.s = s;    }    public void run() {        boolean flag = true;        while (true) {            if (flag) {                s.set("张三", "男");                flag = false;            } else {                s.set("丽丽", "女");                flag = true;            }        }    }}class Output implements Runnable {    Resource s;    Output(Resource s) {        this.s = s;    }    public void run() {        while (true) {            s.info();        }    }}
0 0
原创粉丝点击