深入理解Java中的同步静态方法和synchronized(class)代码块的类锁
一.回顾学习内容
在前面几篇博客中我我们已经理解了synchronized对象锁、对象锁的重入、synchronized方法块、synchronized非本对象的代码块,
链接:https://www.cnblogs.com/SAM-CJM/category/1314992.html
我们来总结一下,上面几篇讲到内容:
1.创建线程类的两个方式:继承Thread类和实现Runable接口。
2.了解了Thread类的几个基本构造器。
3.启动多线程时要使用start方法,不要直接调用run方法。
4.几个多线程中常用的方法。
5.解决一个共享资源被多个线程调用时采用了synchronized同步化一个对象的方法。
6.一个线程可以在进入一个同步化的方法时再去进入这个对象的另外一个同步化方法,这个就是对象锁的重入。
7.为了提高程序的执行效率,我们可以不去直接同步一个方法,直接同步这个方法中有关共享数据的部分,其他部分就是异步执行的。
8.上一篇讲到了使用synchronized同步一个不是本对象的代码块
二.导入问题
我们到现在使用的synchronized方法同步的都是非静态的方法也就是给一个对象上来一把对象锁,那么我们去给一个静态方法会有什么效果呢?
三.同步将静态方法、同步类资源
其实在Java中给一个静态方法上锁就是给一个类上锁,因为类也可以是一个共享资源。
代码如下:
public class SynClass {//这个类为共享资源
//这个静态方法没有被同步
public static void fun() throws InterruptedException {
System.out.println("**************begin**************");
Thread.sleep(4000);
System.out.println("**************end**************");
}
public static void main(String[] args) {
ThreadA t1=new ThreadA();
ThreadA t2=new ThreadA();
t1.start();
t2.start();
}
}
class ThreadA extends Thread {//创建线程
@Override
public void run(){
try {
SynClass.fun();//调用静态方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果就是出现了线程不同步:

修改代码如下:
//这个静态方法被同步
synchronized public static void fun() throws InterruptedException {
System.out.println("**************begin**************");
Thread.sleep(4000);
System.out.println("**************end**************");
}
结果被同步:
说明类也可以是共享资源,同步静态方法也是在同步类资源。
四.类锁和对象锁的认识
假如我们有两把锁一把是类锁,一把是对象锁,那么会出现什么情况呢?
代码如下:
public class SynClassObject {
//创建一个同步的静态的方法
public synchronized static void static_fun(){//类锁
System.out.println("**********静态方法begin*********");
System.out.println("**********静态方法end***********");
}
//创建同步的非静态方法
public synchronized void notStatic_fun(){//对象锁
System.out.println("***********非静态方法begin*************");
System.out.println("***********非静态方法end***************");
}
public static void main(String[] args) {
new SynClassObjectThread1().start();
new SynClassObjectThread2().start();
}
}
class SynClassObjectThread1 extends Thread{//这个线程类调用的是同步化的静态方法
@Override
public void run(){
SynClassObject.static_fun();
}
}
class SynClassObjectThread2 extends Thread{//这个线程类是调用非静态方法
private SynClassObject synClassObject =new SynClassObject();
@Override
public void run(){
synClassObject.notStatic_fun();
}
}
结果入下:
明显他是不同步的,因为对象锁和类锁是两把不同的锁。
同样的道理对于同步静态代码块,也是对类资源实现了一个同步。
***************************往期博客纠错******************************
在此要感谢@用户注册了一次老哥,帮助指出了深入理解Java并发synchronized同步化的代码块不是this对象时的操作中的错误,这一篇文章只是为了说明synchronized关键字同步的是对象而不是方法,我举的列子的确有失偏颇,本人水平有限,如有错误请大家斧正。
************************************************************************
深入理解Java中的同步静态方法和synchronized(class)代码块的类锁的更多相关文章
- 静态同步synchronized方法和synchronized(class)代码块
关键字synchronized还可以应用在static静态方法上,如果这样写,那是对当前的*.java文件对应的Class类进行持锁. package synStaticMethod; /** * C ...
- 理解java中【同步】和【死锁】
一.理解同步 要想解决资源共享的同步操作问题,可以使用两种方法: 使用同步代码块 之前学习过程中,代码块分为四种: l 普通代码块:是直接定义在方法之中的: l 构造块 ...
- java中setDate(Date date)方法和String与Date之间的转换
经常在开发的过程中遇到这样的问题,从数据库中读出来的数据需要转换为对像或者java bean,此时经常使用到setDate(Date date);这样的方法.感觉这是个很简单而又难受的事情,在这里浪费 ...
- Java中Collections的sort方法和Comparable与Comparator的比较
一.Comparable 新建Student1类,类实现Comparable接口,并重写compareTo方法 public class Student1 implements Comparable& ...
- Java中带参数的方法和JavaScript中带参数的函数有什么不同?
javascript是动态语言,是弱类型语言,其参数的使用很灵活:java则是强类型语言,参数的类型必须明确的
- java中线程同步的理解(非常通俗易懂)
转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...
- Java中线程同步的理解 - 其实应该叫做Java线程排队
Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...
- 深入理解java中的synchronized关键字
synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D ...
- 理解Java中的对象,变量和方法
1.对象的创建和销毁 1.1 对象的创建 这里只介绍创建对象与构造方法的关系 (1).每实例化一个对象就会自动调用一次构造方法,实质上这个过程就是创建对象的过程,准确的说,在Java语言中使用new操 ...
随机推荐
- JS设计模式(6)命令模式
什么是命令模式? 定义:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化. 主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录. ...
- markdown的css样式(自己写的)
markdown的css样式,这些是我自己配置的,感觉可以的话你可以添加下,不适合自己的话可以仿照第二种自己写个比较好的css样式. 第一种 /* RESET ==================== ...
- oracle 老用户数据导入新建用户
$sqlplus/nolog #使用PLSQL进入oracleSQL>conn/as sysdba #进入sysdba权限CREATE DIRECTORY datadir1 AS ' ...
- Python3 tkinter基础 Menu 添加菜单栏
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- jackson中@JsonProperty、@JsonIgnore等常用注解总结
本文为博主原创,未经允许不得转载: 最近用的比较多,把json相关的知识点都总结一下,jackjson的注解使用比较频繁, jackson的maven依赖 <dependency> < ...
- 如何恢复IIS出厂默认设置
How to restore IIS settings and Default Web Site? http://superuser.com/questions/704850/how-to-resto ...
- Git 与 GitHub 入门级
今天我们来搞一下Git 这东西虽然没啥搞头儿,但是开发当中还必须得会用,谁让你我都是苦逼的开发呢~~~~ 一.下载与安装 这玩意简单,给你赋个图片,自己研究一下~~~~ 1.官网:https://gi ...
- 【转载】Selenium WebDriver的简单操作说明
转载自:http://blog.csdn.net/xiao190128/article/details/49784121 1.打开一个测试浏览器 对浏览器进行操作首先需要打开一个浏览器,接下来才能对浏 ...
- 自己封装myLocalStorage,使其有有效期
项目中遇见 cookie 值存不上,what fuck?什么情况,不知道.用$.cookie 和原生的 cookie 都不行,存上值,就被删了一样.找不见地方.考虑到项目比较大,去找得代价,还不如换种 ...
- [原][译]JSBSim官方源码文档翻译(google翻译)
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS DOCUMENTATION ...