同步静态方法

synchronized还可以应用在静态方法上,如果这么写,则代表的是对当前.java文件对应的Class类加锁。看一下例子,注意一下printC()并不是一个静态方法:

public class ThreadDomain25
{
public synchronized static void printA()
{
try
{
System.out.println("线程名称为:" + Thread.currentThread().getName() +
"在" + System.currentTimeMillis() + "进入printA()方法");
Thread.sleep(3000);
System.out.println("线程名称为:" + Thread.currentThread().getName() +
"在" + System.currentTimeMillis() + "离开printA()方法");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} public synchronized static void printB()
{
System.out.println("线程名称为:" + Thread.currentThread().getName() +
"在" + System.currentTimeMillis() + "进入printB()方法");
System.out.println("线程名称为:" + Thread.currentThread().getName() +
"在" + System.currentTimeMillis() + "离开printB()方法"); } public synchronized void printC()
{
System.out.println("线程名称为:" + Thread.currentThread().getName() +
"在" + System.currentTimeMillis() + "进入printC()方法");
System.out.println("线程名称为:" + Thread.currentThread().getName() +
"在" + System.currentTimeMillis() + "离开printC()方法");
}
}

写三个线程分别调用这三个方法:

public class MyThread25_0 extends Thread
{
public void run()
{
ThreadDomain25.printA();
}
}
public class MyThread25_1 extends Thread
{
public void run()
{
ThreadDomain25.printB();
}
}
public class MyThread25_2 extends Thread
{
private ThreadDomain25 td; public MyThread25_2(ThreadDomain25 td)
{
this.td = td;
} public void run()
{
td.printC();
}
}

写个main函数启动这三个线程:

public static void main(String[] args)
{
ThreadDomain25 td = new ThreadDomain25();
MyThread25_0 mt0 = new MyThread25_0();
MyThread25_1 mt1 = new MyThread25_1();
MyThread25_2 mt2 = new MyThread25_2(td);
mt0.start();
mt1.start();
mt2.start();
}

看一下运行结果:

线程名称为:Thread-0在1443857019710进入printA()方法
线程名称为:Thread-2在1443857019710进入printC()方法
线程名称为:Thread-2在1443857019710离开printC()方法
线程名称为:Thread-0在1443857022710离开printA()方法
线程名称为:Thread-1在1443857022710进入printsynchronized B()方法
线程名称为:Thread-1在1443857022710离开printB()方法

从运行结果来,对printC()方法的调用和对printA()方法、printB()方法的调用时异步的,这说明了静态同步方法和非静态同步方法持有的是不同的锁,前者是类锁,后者是对象锁

所谓类锁,举个再具体的例子。假如一个类中有一个静态同步方法A,new出了两个类的实例B和实例C,线程D持有实例B,线程E持有实例C,只要线程D调用了A方法,那么线程E调用A方法必须等待线程D执行完A方法,尽管两个线程持有的是不同的对象。

同步类.Class

同步synchronized(class) 和同步静态方法都是一样,同步的都是当前的类锁 

类Service




结果


实验证明  静态方法  和静态类.class 锁 都是一样获取的类锁




数据String的常量池特性
在使用同步的时候,如果要锁定String , 两个线程运行的时候,很可能有一个无限等待无法获取到锁





这里就是String 常量池带来的奇葩问题 , 要特别注意







java 多线程10:synchronized锁机制 之 锁定类静态方法 和锁定类.Class 和 数据String的常量池特性的更多相关文章

  1. java 多线程9 : synchronized锁机制 之 代码块锁

    synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...

  2. java 多线程8 : synchronized锁机制 之 方法锁

    脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数 ...

  3. Java多线程学习——synchronized锁机制

    Java在多线程中使用同步锁机制时,一定要注意锁对对象,下面的例子就是没锁对对象(每个线程使用一个被锁住的对象时,得先看该对象的被锁住部分是否有人在使用) 例子:两个人操作同一个银行账户,丈夫在ATM ...

  4. String对象常量池特性对synchronized对象的影响

    一 .什么是String的常量池特性 对于字符串对象有两种创建方法,如下: 直接赋值法: String str1="直接赋值创建字符串"; 创建对象法: String str2=n ...

  5. java 多线程并发 synchronized 同步机制及方式

    2. 锁机制 3. 并发 Excutor框架 4. 并发性与多线程介绍 1. synchronized  参考1. synchronized 分两种方式进行线程的同步:同步块.同步方法 1. 方法同步 ...

  6. 2.2.10数据类型String的常量池特性

    在JVM中具有String常量池缓存的功能 package com.cky.test; /** * Created by edison on 2017/12/8. */ public class Te ...

  7. Java多线程,对锁机制的进一步分析

    1 可重入锁 可重入锁,也叫递归锁.它有两层含义,第一,当一个线程在外层函数得到可重入锁后,能直接递归地调用该函数,第二,同一线程在外层函数获得可重入锁后,内层函数可以直接获取该锁对应其它代码的控制权 ...

  8. Java多线程5:Synchronized锁机制

    一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...

  9. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

随机推荐

  1. heap与stack的差

    本文内容来源于<程序猿面试宝典>第三版. 在进行C/C++编程时.常常将操作的内存分下面几个类别: 栈区(stack):由编译器自己主动分配和释放,存放函数的參数值.局部变量的值等. 其操 ...

  2. Redis学习(7)-通用命令

    keys pattern: 获取所有与pattern匹配的key,返回所有与该key匹配的keys. 通配符: *表示任意一个或多个字符串. ?表示一个字符. 例如: 查询所有的key:keys * ...

  3. java 管道流代码示例

    import java.io.IOException;import java.io.PipedInputStream;import java.io.PipedOutputStream; public ...

  4. LINUX下一款不错的网站压力测试工具webbench

    LINUX下一款不错的网站压力测试工具webbench 分类: Linux 2014-07-03 09:10 220人阅读 评论(0) 收藏 举报 [html] view plaincopy wget ...

  5. kubernetes中使用NFS创建pv_pvc

    Persistent Volume(持久化卷)简称PV, 是一个K8S资源对象,我们可以单独创建一个PV, 它不和Pod直接发生关系, 而是通过 Persistent Volume Claim, 简称 ...

  6. Linux命令-安全复制命令:scp

    scp是有Security的文件copy,基于ssh登录.操作起来比较方便,比如要把当前一个文件copy到远程另外一台主机上. 命令格式: scp [可选参数] 源文件 目标文件 scp 本地文件 远 ...

  7. 匿名管道和pipe函数

    一.进程间通信 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2 ...

  8. Unix环境高级编程(九)信号

    信号时软中断,很多比较重要的应用程序都需要处理信号,信号提供了一种处理异步事件的方法.每个信号都一个名字,以SIG开头,在<signal.h>头文件中定义信号类型,都是正整数(信号编号). ...

  9. if else和switch的效率

    switch和if-else相比,由于使用了Binary Tree算法,绝大部分情况下switch会快一点,除非是if-else的第一个条件就为true. 说实话  我也没有深入研究过这个问题的根源  ...

  10. Linux前台、后台、挂起、退出、查看命令汇总

    command &  直接在后台执行程序 ctrl+c 退出前台的命令,不再运行 ctrl+z挂起前台命令暂停运行,回到shell命令行环境中 bg    将刚挂起的命令放到后台执行 bg % ...