synchrozied方法和synchrozied修饰代码块的区别

synchroized是jvm提供的,无需手动控制它可以自动对多线程访问的资源进行加锁与解锁,它可以修饰方法,也可以修饰代码块.

这边博客记录下个人对synchrozied的理解如下:

1.为什么Java要提供synchronized?

  当多条线程去对一个类的实例变量进行修改,这时会发生变量的不确定性.为解决这个问题,使用synchronized修饰,使得在某一时刻,只能有一条线程进行操作.实现的方式是加锁与解锁.

2.实例演示多线程访问共享变量产生的问题.  

public class ManyThreadModify implements Runnable{

    private int value = 10;
    @Override
    public void run() {
        for(int i = 0; i < 10; i++) {
            value--;
            System.out.println(Thread.currentThread().getName() + "修改value的值为:" + value);
        }
    }
    
    public static void main(String[] args) {
        ManyThreadModify mm = new ManyThreadModify();
        //使用实现Runnable接口的方式可以共享变量,每启动的线程都是以target形式启动的
        new Thread(mm , "线程01").start();
        new Thread(mm , "线程02").start();
    }
}

   可以看到,出现了value的值两次等于8的情况,这就是线程不安全造成的,在run方法上加上synchronize修饰可以解决这个问题.

3.synchrozied修饰方法和修饰代码块的区别

  修饰方法:synchronize public void test(){}

  修饰代码块:synchronize(锁对象){  //代码块 }

  区别:

public class SynchronizedMethodAndCode{
	//synchronize修饰方法
	public synchronized void test01() {
		try {
			System.out.println("this is method test01...");
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public void test02() {
		//synchronize修饰代码块,锁对象为当前对象
		synchronized (this) {
			System.out.println("this is method test02...");
		}
	}
	public void test03() {
		String str = "s";
		//synchronize修饰代码块,锁对象为str
		synchronized (str) {
			System.out.println("this is method test03...");
		}
	}
}

   启动线程访问

public class SynchroziedMain {

	public static void main(String[] args) {
		SynchronizedMethodAndCode sc = new SynchronizedMethodAndCode();
		//启动线程1访问test01方法
		new Thread(new Runnable() {
			@Override
			public void run() {
				sc.test01();
			}
		}).start();
		
		//启动线程2访问test02方法
		new Thread(new Runnable() {
			@Override
			public void run() {
				sc.test02();
			}
		}).start();
		
		//启动线程3访问test03方法
		new Thread(new Runnable() {
			@Override
			public void run() {
				sc.test03();
			}
		}).start();
	}
}

   可以看到打印结果,

分析:启动线程1访问test01方法时遇到sleep(3000),线程1没有释放锁资源,在这里,锁资源就是当前对象,锁被线程1拿在了手里没有释放,而test02方法的锁对象this也是当前对象,所以线程1和线程2使用的是同一把锁,线程2等待线程1     sleep()结束才能获得锁,进入test02方法的打印代码中,所以线程3先打印了,因为它的锁是自己定义的一个String对象.

 

总结:synchronize修饰方法的锁对象只能是this当前对象

   synchronize修饰代码块可以修改锁对象

 

 

转载于:https://www.cnblogs.com/yuchangying/p/9364607.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值