一.回顾学习内容

在前面几篇博客中我我们已经理解了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)代码块的类锁的更多相关文章

  1. 静态同步synchronized方法和synchronized(class)代码块

    关键字synchronized还可以应用在static静态方法上,如果这样写,那是对当前的*.java文件对应的Class类进行持锁. package synStaticMethod; /** * C ...

  2. 理解java中【同步】和【死锁】

    一.理解同步 要想解决资源共享的同步操作问题,可以使用两种方法: 使用同步代码块 之前学习过程中,代码块分为四种: l         普通代码块:是直接定义在方法之中的: l         构造块 ...

  3. java中setDate(Date date)方法和String与Date之间的转换

    经常在开发的过程中遇到这样的问题,从数据库中读出来的数据需要转换为对像或者java bean,此时经常使用到setDate(Date date);这样的方法.感觉这是个很简单而又难受的事情,在这里浪费 ...

  4. Java中Collections的sort方法和Comparable与Comparator的比较

    一.Comparable 新建Student1类,类实现Comparable接口,并重写compareTo方法 public class Student1 implements Comparable& ...

  5. Java中带参数的方法和JavaScript中带参数的函数有什么不同?

    javascript是动态语言,是弱类型语言,其参数的使用很灵活:java则是强类型语言,参数的类型必须明确的

  6. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  7. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  8. 深入理解java中的synchronized关键字

    synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D ...

  9. 理解Java中的对象,变量和方法

    1.对象的创建和销毁 1.1 对象的创建 这里只介绍创建对象与构造方法的关系 (1).每实例化一个对象就会自动调用一次构造方法,实质上这个过程就是创建对象的过程,准确的说,在Java语言中使用new操 ...

随机推荐

  1. Docker Swarm volume 数据持久化

    Docker Swarm volume 数据持久化 volume 是将宿主级的目录映射到容器中,以实现数据持久化. 可以用两种方式来实现: volume 默认模式:工作节点宿主机数据同步到容器内. v ...

  2. 01:golang开发环境

    1.1 go环境安装 1.go下载安装 官方:https://golang.org/dl 国内: https://golang.google.cn/dl/ https://www.golangtc.c ...

  3. 对比Python中_,__,xx__xx

      对比Python中_,__,xx__xx _ 的含义 不应该在类的外面访问,也不会被from M import * 导入. Python中不存在真正的私有方法.为了实现类似于c++中私有方法,可以 ...

  4. 剑指offer(18)二叉树的镜像

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ ...

  5. vector、map 判断某元素是否存在、查找指定元素

    一.vector 1.判断某元素是否存在 vector<string> vStr; int nRet = std::count(vStr.begin(), vStr.end(), &quo ...

  6. [译]课程 1: 使用 Quartz

    译者注: 原文在这 Lesson 1: Using Quartz 在你使用调度器之前, 你需要先实例化(能猜到是谁么?). 要实例化, 请使用 ISchedulerFactory 的实现. 译者注: ...

  7. Learning-Python【28】:基于TCP协议通信的套接字

    什么是 Socket Socket 是应用层与 TCP/IP 协议通信的中间软件抽象层,它是一组接口.在设计模式中,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Sock ...

  8. vue实现 toggle显示隐藏效果

    背景介绍jQuery中有个toggle()方法,可以切换元素的显示状态,在用vue时如果不引入jQuery如何实现这种效果?使用场景常见有三种场景:1.控制页面中一个dom元素2.控制页面中多个dom ...

  9. DAY11 函数(二)

    一.函数的对象 1.1定义:函数名就是存放了函数的内存地址,存放了内存地址的变量都是对象,即 函数名 就是 函数对象 1.2函数对象的应用 1 可以直接被引用 fn = cp_fn def fn(): ...

  10. 雷林鹏分享:jQuery EasyUI 数据网格 - 创建自定义视图

    jQuery EasyUI 数据网格 - 创建自定义视图 在不同的情况下,您可能需要为数据网格(datagrid)运用更灵活的布局.对于用户来说,卡片视图(Card View)是个不错的选择.这个工具 ...