博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
synchrozied方法和synchrozied修饰代码块的区别
阅读量:4478 次
发布时间:2019-06-08

本文共 2298 字,大约阅读时间需要 7 分钟。

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

你可能感兴趣的文章
C#与数据结构--图的遍历
查看>>
ispy 编译笔记
查看>>
bzoj1067——SCOI2007降雨量(线段树,细节题)
查看>>
day 1
查看>>
洛谷P1282 多米诺骨牌【线性dp】
查看>>
数据类型的提升(promotion)
查看>>
Thead是不能返回值的,但是作为更高级的Task当然要弥补一下这个功能。
查看>>
Android呼叫转移跳转到拨号盘 “#”号显示不出来
查看>>
Python中的生成器与yield
查看>>
JQuery 的Bind()事件
查看>>
Maven 常用配置
查看>>
Objects源码解析
查看>>
video
查看>>
栈的c语言顺序实现(动态申请空间)
查看>>
【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET
查看>>
获取子iframe框架的元素
查看>>
WordCount bug修复录
查看>>
承载进程 (vshost.exe)
查看>>
[转]WPF MVVM 实战
查看>>
[转载] Python 标准库 urllib2 的使用细节
查看>>