深入理解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操 ...
随机推荐
- Python sqlalchemy orm 常用操作
增add # 创建表1 # 注:高级封装 import sqlalchemy # 调用链接数据库 from sqlalchemy import create_engine # 调用基类Base fro ...
- 程序员的快速开发框架:Github上 10 大优秀的开源后台控制面板
程序员的快速开发框架:Github上 10 大优秀的开源后台控制面板 Web 开发中几乎的平台都需要一个后台管理,但是从零开发一套后台控制面板并不容易,幸运的是有很多开源免费的后台控制面板可以给开发者 ...
- git分散式版本管理系统,从安装到基本使用
首先,当然是安装git了,不用寻思,官网下载即可 https://git-scm.com/downloads 第二是设置账户,鼠标右键,选择git bush,在命令窗口中进行设置 git config ...
- Day 10733 使用独立安装包安装.Net Framework 4.6.2时,提示『无法建立到信任根颁发机构的证书链』
出现该问题的原因是未能更新本机的受信任证书颁发机构证书列表,导致安装包验证失败,以下几种情况可以造成此问题: 1.安装该运行库的系统未接入互联网: 2.安装该运行库的系统所在的网络环境,屏蔽了对微软受 ...
- centos6.5下安装Nginx
链接: https://www.jb51.net/article/118595.htm
- innoDB锁小结
innodb的锁分两类:lock和latch. 其中latch主要是保证并发线程操作临界资源的正确性,要求时间非常短,所以没有死锁检测机制.latch包括mutex(互斥量)和rwlock(读写锁). ...
- Hadoop之简单文件读写
文件简单写操作: import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataOutputStream ...
- leecode第一百六十题(相交链表)
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
- Angular 学习笔记 (久久没有写 angular 常会忘记的小细节)
由于经常跑去写后端, 而且一些就几个月...很多 ng 的东西就忘掉了. 写在这里方便复习呗. 1. async pipe 没有 resolve 前返回的值是 null 2 view componen ...
- postman(三):添加断言
进行接口测试时,添加断言时必不可少的,断言就是判断响应内容与预期返回是否一致 进行接口测试时,添加断言时必不可少的,断言就是判断响应内容与预期返回是否一致 postman可以在请求模块的Tests ...