深入理解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操 ...
随机推荐
- 自制操作系统Antz(4)——进入保护模式 (下) 实现内核并从硬盘载入
Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...
- (转载)Unity学习笔记:关于Dropdown的学习
今天组长让我写一个界面,其中用到了下拉条,我的印象还停留在以前的NGUI有现成的组件,但是uGUI没有的那阶段,组长跟我说uGUI现在也有了,研究了一下,发现real方便哦,今天就来简单说一下用法吧. ...
- PHP冒泡排序-手写
<?php $a = [1,3,5,2,9,6]; for ($i = 0 ;$i < count($a) ;$i++) { for ($j = $i + 1;$j < count( ...
- Linux 环境下jmeter 安装和配置
1. 下载和安装JDK vim /etc/profile export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_92 export JRE_HOME=$JAVA_HOME/jr ...
- scala基础学习(一)
scala学习 scala与java的不同之处: 1.scala中任何一个操作符都是一个方法. s = 1+2; 可以写作:s=(1).+(2) 2.异常捕获采用模式匹配的方式. try { v ...
- Eclispe创建maven工程缺失web.xml报web.xml is missing and <failOnMissingWebXml> is set to true的错误
Eclispe创建maven工程缺失web.xml报web.xml is missing and <failOnMissingWebXml> is set to true的错误,一看,还缺 ...
- 更改npm淘宝源,并设置cnpm
一.通过命令配置1. 命令 npm config set registry https://registry.npm.taobao.org2. 验证命令 npm config get registry ...
- 如何进入docker 使用root用户的方式
docker exec -it --user root <container id> /bin/bash
- Asp.net core 学习笔记 (library)
refer : https://docs.microsoft.com/en-us/dotnet/core/tutorials/library-with-visual-studio https://do ...
- jq初入行常用动画
--jq动画分类--(1)jQuery的动画其实就是将之前提到过的各种特效进行封装,并对其性能进行优化.(2)jQuery动画分为三个部分:非自定义动画,自定义动画,和全局动画设置. 一.非自定义动画 ...