synchronized、脏读、volatile

synchronized可以加在方法体上,也可以使用在对象上

		try {
			
			synchronized (list) {
				if(list.getSize() < 1){
					Thread.sleep(2000);
					list.add(data);
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
    public synchronized void method() {

        try {

            System.out.println("B:" + Thread.currentThread().getName());
            Thread.sleep(5000);
            System.out.println("end B");
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

这种同步的锁必须是要在多线程访问同一个对象实例的时候才有用,否则访问的是不同的实例对象那就一点用也没,还浪费了效率
与synchronized对应的最简单的场景就是脏读,显然解决该问题的最佳方式就是加入synchronized

public class PublicVar {

    public String username = "A";
    public String password = "AA";

    public void setValue(String username, String password){

        try {

            this.username = username;
            Thread.sleep(5000);
            this.password = password;
            System.out.println("setValue method thread name = " + Thread.currentThread().getName() + " username = " + username + " password = " + password );

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void getValue() {

        System.out.println("getValue method thread name = "
                + Thread.currentThread().getName() + " username = " + username
                + " password = " + password
        );
    }

    public static void main(String[] args) {

        try {

            PublicVar publicVar = new PublicVar();
            ThreadA threadA = new ThreadA(publicVar);
            threadA.start();
            threadA.sleep(200);
            publicVar.getValue();

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
}

public class ThreadA extends Thread {

    private PublicVar publicVar;

    public ThreadA(PublicVar publicVar){
        super();
        this.publicVar = publicVar;
    }

    public void run(){
        super.run();
        publicVar.setValue("B", "BB");
    }

}

接下来介绍volatile

public class RunThread extends Thread {

    /**
     * volatile的主要作用就是当线程访问isRuning这个变量时强制从公共堆栈中取值(当加上该修饰符该值就会被强制弄到主内存中)
     * 使用volatile增加了实例变量在多个线程之间的可见性,但其关键字最致命的缺点是不支持原子性
     */
    volatile private boolean isRunning = true;

    public boolean isRunning() {
        return isRunning;
    }

    public void setRunning(boolean running) {
        isRunning = running;
    }

    @Override
    public void run() {

        System.out.println("run method");

        while (isRunning == true) {

        }

        System.out.println("run method end");
    }

    public static void main(String[] args) {

        try {

            RunThread run = new RunThread();
            run.start();
            Thread.sleep(1000);
            run.setRunning(false);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

volatile的主要作用就是当线程访问isRuning这个变量时强制从公共堆栈中取值(当加上该修饰符该值就会被强制弄到主内存中),使用volatile增加了实例变量在多个线程之间的可见性,但其关键字最致命的缺点是不支持原子性。
volatile与sync的区别:
1、volatile是线程同步的轻量级实现,所以volatile性能比synchronized要好,并且volatile只能修饰变量,sync能修饰方法和代码块。
2、多线程访问volatile不会发生阻塞,而sync会
3、volatile能保证数据的可见性,而不能保证原子性,而sync可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存中的数据做同步
4、volatile解决的是变量在多个线程之间的可见性,而sync解决的是多个线程之间访问资源的同步性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值