synchronized :java内置关键字,被保存在对象头中,而一个对象则是由对象头、实例数据、对其填充三部分组成。

很多时候大家伙都惯性地将synchronized称为一个重量级锁,理由是synchronized性能开销较重;这在JDK1.6之间这样说是没毛病的,但是在JDK1.6及以后,还这样认为那就欠妥了,因为在JDK1.6及以后JVM层面对它作了优化,可以由轻到重分为:偏向锁->轻量级锁->重量级锁;并且可自动进行锁粒度的切换升级。所以从性能开销的程度来讲,已经变得和Lock相差无几了!

一般来说synchronized有三种用法:

一、作用于静态方法

给当前类加锁,又可称之静态方法锁:可以修饰在静态方法名前: public static synchronized void inc() :

又可以修饰在静态方法里的代码块(如下): synchronized (Method.class){}

package com.wuqx.demo;public class Method { private static int count = 0; public static void inc(){ synchronized (Method.class){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } count ++; } } public static void main(String[] args) { for (int i = 0; i < 100; i++) { //不要new太多的线程,避免操作系统假死,出现找不到主类的错误 new Thread(()->Method.inc()).start(); } while(Thread.activeCount()>1){ //这里也可以使用Thread.sleep()方法进行阻塞,避免得到错误的结果 Thread.yield(); } System.out.println("result:"+Method.count); }}

总结:可以保证多个实例对象调用静态方法时保证其安全性

二、作用于实例方法

即对象锁,对同一个对象加锁,保证多个线程访问同一个对象时线程的安全,进入同步代码前要获得当前对象的锁,

(1)多个线程对同一对象进行访问,代码清单如下:

package t;public class Method implements Runnable{ private static int count = 0; public synchronized void run(){ for(int i=0; i<5; i++){ System.out.println(Thread.currentThread().getName()+":"+count++); } } public static void main(String[] args) { Method md = new Method(); Thread thread1 = new Thread(md,"thread1"); Thread thread2 = new Thread(md,"thread2");  thread1.start(); thread2.start();  int i = 0; while(Thread.activeCount()>1){ System.out.println("第"+i+++"次出让系统资源"); Thread.yield(); } System.out.println("result:"+Method.count); }}

运行结果:

(2)多个线程对不同对象访问,则会造成线程的安全问题;因为两个对象之间没有关系,是独立的,内存地址,保存在对象头里的锁也不相同,所以会造成线程安全问题。代码清单如下(两个线程执行两个对象):

package t;

public class Method implements Runnable{

private static int count = 0;

public synchronized void run(){

for(int i=0; i<5; i++){

System.out.println(Thread.currentThread().getName()+":"+count++);

}

}

public static void main(String[] args) {

Method md = new Method();

Method md1 = new Method();

Thread thread1 = new Thread(md,"thread1");

Thread thread2 = new Thread(md1,"thread2");

thread1.start();

thread2.start();

}

}

​​运行结果如下:

可见这种情况只能通过将run方法里的方法静态化,通过类锁去解决:代码清单如下:

​​package t;public class Method implements Runnable{ private static int count = 0; public void run(){ //这里加与不加synchronized 效果都一样,可以思考下为什么 inc(); } public static synchronized void inc(){ for(int i=0; i<5; i++){ System.out.println(Thread.currentThread().getName()+":"+count++); } } public static void main(String[] args) { Method md = new Method(); Method md1 = new Method(); Thread thread1 = new Thread(md,"thread1"); Thread thread2 = new Thread(md1,"thread2");  thread1.start(); thread2.start(); }}

运行结果如下:

三、修饰代码快

写法为synchronized(obj){},实际工程上都用写为synchronized(this){}, 这是对于多个线程访问同一对象,代码清单如下;如果多个线程访问不同对象,那么这样写还是不能保证线程的安全,因为将对象不同,锁也就不是同一把锁了,这样就同样需要类锁去实现了。

package t;

public class Method implements Runnable{

private static int count = 0;

public void run(){

inc();

}

public void inc(){

synchronized(this){

for(int i=0; i<5; i++){

System.out.println(Thread.currentThread().getName()+":"+count++);

}

}

}

public static void main(String[] args) {

Method md = new Method();

Thread thread1 = new Thread(md,"thread1");

Thread thread2 = new Thread(md,"thread2");

thread1.start();

thread2.start();

}

}

运行结果:

​​​

如果觉得对自己有帮助的话,不妨关注点赞转发支持下哦!​​

相关导读:

synchronized与Lock的区别

try catch用法_synchronized用法总结相关推荐

  1. try、catch、finally用法总结

    一.异常的处理:抓抛模型过程一:"抛":程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象.并将此对象抛出.一旦抛出对象以后,其后的代码就不再执行.关于 ...

  2. Java里try catch的简单用法

    Java里try catch的简单用法: Java里try catch的简单用法: 1.try+catch 程序的流程是:运行到try块中,如果有异常抛出,则转到catch块去处理.然后执行catch ...

  3. try 、catch、finally用法总结

    1. try .catch.finally用法总结 1.在进行异常的处理之后,在异常的处理格式中还有一个finally语句,那么此语句将作为异常的统一出口,不管是否产生了异常,最终都要执行此段代码.2 ...

  4. java中 try用法,Java里try catch的简单用法

    优质回答 回答者:temps1991 Java里try catch的简单用法: 1.try+catch 程序的流程是:运行到try块中,如果有异常抛出,则转到catch块去处理.然后执行catch块后 ...

  5. 【Java 泛型】泛型用法 ( 泛型类用法 | 泛型方法用法 | 泛型通配符 ? | 泛型安全检查 )

    文章目录 一.泛型类用法 二.泛型方法用法 三.泛型通配符 <?> 四.泛型安全检查 五.完整代码示例 1.泛型类 / 方法 2.main 函数 一.泛型类用法 泛型类用法 : 使用时先声 ...

  6. JavaScript中try, catch, throw的用法

    文章出自个人博客https://knightyun.github.io/2019/09/02/js-try,转载请申明. 程序在运行中难免遇到 bug,所以就需要好的调试手段找出问题所在,try, c ...

  7. JAVA学习心得——异常处理try、catch、finally用法

    要了解try.catch.finally的用法,首先了解什么是异常. 异常就是代码出现了问题,不同寻常的意思. java语言把程序运行过程中所发生的不正常严重错误成为异常. 异常的结构: 异常也是有子 ...

  8. try、catch、finally用法

    try { //执行的代码,其中可能有异常.一旦发现异常,则立即跳到catch执行.否则不会执行catch里面的内容 } catch { //除非try里面执行代码发生了异常,否则这里的代码不会执行 ...

  9. try catch finally的用法

    1.不使用try...catch出现异常后,后面的代码都不会运行了 login() {console.log(b);console.log('hhhhhhhh');}, 2.使用了try...catc ...

最新文章

  1. CMD命令,常驻内存的与外部的介绍 还有CMD格式化
  2. Java获得时间 String与Timestamp互转
  3. ssl1063-统计数字【哈希表】
  4. python读取单元格部分内容_Python提取表格一定区域的内容
  5. 跨业自学党的第一次面试
  6. 怎么一步一步的开一家公司?
  7. python perl 正则_为什么说perl的正则表达式功能比Python强大
  8. python中文乱码解决
  9. Sprint回顾会议
  10. pcs9000系统plat服务器,CSD361現场调试手册.docx
  11. 可靠性评价类毕业论文文献都有哪些?
  12. SQL数据库-第一次试验-表与视图的基本操作
  13. useRoutes() may be used only in the context of a <Router> component.
  14. android蓝牙浅析
  15. 达思SQL数据库修复软件1.7(支持碎片重组、支持勒索病毒加密的sql数据库修复软件)
  16. Java设计模式入门
  17. APQ8064 camera AF 调试
  18. TPM零知识学习十一 —— tpm全安装流程复盘(下)
  19. H5网页播放器EasyPlayer.js如何实现直播视频实时录像?
  20. 苹果库乐队怎么玩_苹果安卓手机最简单换铃声方法,无需电脑,简单一步就能换成流行歌曲...

热门文章

  1. shell脚本报错:-bash: xxx: /bin/sh^M: bad interpreter: No such file or directory
  2. 长连接和Keepalive
  3. chromium net库设计
  4. MySQL(二): 表的增删查改
  5. C++ 类和对象(二):构造函数、析构函数、拷贝构造函数、运算符重载
  6. navicat for mysql 连接时报错:1251-Client does not support authentication protocol requested by server
  7. [九]RabbitMQ-客户端源码之Consumer
  8. 面试官:DDD如何指导微服务拆分?90%的程序员都答不上来!
  9. 是MPEG没有未来,还是未来不需要MPEG
  10. 5月19-20日的上海 来一次纯粹的WebRTC之旅