单例中的线程不安全性

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

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();
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值