今天遇到了一个关于synchronized的一个问题,关于其持有锁的问题。这个问题以前是有看过相关文章的,但是一直没有记录,今天大概记录一下当前的认知。

对于静态方法,synchronized的使用的锁实际上是以Class对象作为锁,对于非静态方法,持有的锁为方法所在的对象。可能有点难以理解,但是,仔细想想,静态方法是类级别的,而非静态方法属于对象级别的。这样或许好理解一下。

关于synchronized的常规用法

同步控制块。进入此段代码前,必须得到syncObject对象的锁,如果其他线程正在持有这个锁,那么就得等到这个线程释放以后,才能进入临界区。

synchronized(syncObject){
  //处理逻辑
}

亦或使用其修饰整改方法,这个时候,就需要注意到开头说的锁的问题了。对于不同级别的方法,所持有的锁是不同的。

synchronized fun(){
  //处理逻辑
}

下面我们,通过demo来说这个情况。注释代码,说明了静态方法与非静态方法使用不同的锁。三个线程并发,为了说明即使在同一个对象当中,也必须使用相同的对象锁,synchronized才能确保临界区同一个时刻只能被一个线程访问。结果中先输出fun2表明线程2并没有因线程1持有当前demo对象的锁而被阻塞,但是线程3却被阻塞了。

package com.woniu.test.concurrency;

import java.util.HashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class TestSynchronized { public static void main(String[] args) throws InterruptedException {
// ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
// executor.scheduleAtFixedRate(new Demo(), 1, 2, TimeUnit.SECONDS);
//
// while(true) {
// System.out.println(System.currentTimeMillis() + ", woniu id is " + Demo.getMap().get("woniu"));
// Thread.sleep(1000);//这里的延迟会因updateMap持有相同的锁,导致延迟的时间变得更长
// } final Demo demo = new Demo(); new Thread(new Runnable() { public void run() {
try {
demo.fun1();
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
).start(); Thread.sleep(1000);
new Thread(new Runnable() { public void run() {
try {
demo.fun2();
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
).start(); new Thread(new Runnable() { public void run() {
try {
demo.fun3();
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
).start();
}
} class Demo implements Runnable { private static HashMap<String, Integer> map = new HashMap<String, Integer>();
private Object obj = new Object();
public Demo() {
map.put("woniu", 1);
} public void run() {
try {
updateMap();
} catch (InterruptedException e) {
e.printStackTrace();
}
} //如果updateMap没有使用static进行修饰,此处休息3000ms,对于主线程的while循环式不起作用的,因为两者使用的锁不一致。
public synchronized static void updateMap() throws InterruptedException {
System.out.println("begin to update");
Thread.sleep(3000);
map.put("woniu", map.get("woniu") + 1);
System.out.println("update end");
} public synchronized static HashMap<String, Integer> getMap() {
return map;
} public synchronized void fun1() throws InterruptedException {
Thread.sleep(3000);
System.out.println("this is fun1()");
} public void fun2() throws InterruptedException {
synchronized (obj) {
System.out.println("this is fun2()");
}
} public void fun3() throws InterruptedException {
synchronized (this) {
System.out.println("this is fun3()");
}
}
}

synchronized一个(二)的更多相关文章

  1. 二维码合成,将苹果和安卓(ios和android)合成一个二维码,让用户扫描一个二维码就可以分别下载苹果和安卓的应用

    因为公司推广的原因,没有合适的将苹果和安卓(ios和android)合成一个二维码的工具. 因为这个不难,主要是根据浏览器的UA进行判断,所以就自己开发了一个网站 网站名称叫:好推二维码  https ...

  2. [LeetCode] Search a 2D Matrix II 搜索一个二维矩阵之二

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  3. [LeetCode] Search a 2D Matrix 搜索一个二维矩阵

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  4. ytu 1050:写一个函数,使给定的一个二维数组(3×3)转置,即行列互换(水题)

    1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 154  Solved: 112[ ...

  5. 正确运用synchronized和二次判断 实现多线程安全

    正确运用synchronized和二次判断 实现多线程安全,做出高效二符合预期的程序,特别是多个线程跑一个对象的时候,如下图所示:  测试代码如下: 特别注意if(shutdownRequested) ...

  6. [CareerCup] 11.6 Search a 2D Matrix 搜索一个二维矩阵

    11.6 Given an M x N matrix in which each row and each column is sorted in ascending order, write a m ...

  7. [CareerCup] 13.10 Allocate a 2D Array 分配一个二维数组

    13.10 Write a function in C called my2DAlloc which allocates a two-dimensional array. Minimize the n ...

  8. new一个二维数组

    .定义一个二维数组 char **array1 array1 = new char *[x]; for(i=0;i<x;++i) array1[i] = new char[y]; ...用的时候 ...

  9. C语言里的指针探析——type *name[] 在函数参数里面,是一个二维指针

    type *name[] 在函数参数里面声明和不在函数里面声明其实不一样. type *name[] 如果在函数参数里声明,则name 是一个二维指针,并不是一个指针数组,而如果不在函数参数里声明,则 ...

  10. 公司开发的APP,如何生成一个二维码,供客户下载使用

    1.其实和简单,因为一般的用户使用扫一扫,大多数都是用微信自带的扫一扫工具 而,微信打开的二维码页面,会自动屏蔽apk文件,所以显然把apk的url生成一个二维码,让用户扫一扫就能直接下载,这样是行不 ...

随机推荐

  1. 滚动侦测scrollspy

    <!doctype html><html> <head><meta charset="utf-8"><meta http-eq ...

  2. centos shell基础 alias 变量单引号 双引号 history 错误重定向 2>&1 jobs 环境变量 .bash_history source配置文件 nohup & 后台运行 cut,sort,wc ,uniq ,tee ,tr ,split, paste cat> 2.txt <<EOF 通配符 glob模式 发邮件命令mail 2015-4-8 第十二节课

    centos shell基础知识 alias  变量单引号 双引号   history 错误重定向 2>&1  jobs  环境变量 .bash_history  source配置文件 ...

  3. MyBatis—mybatis-config.xml配置介绍

    在定义sqlSessionFactory时需要指定MyBatis主配置文件: Xml代码   说明: 收藏代码 1.  <bean id="sqlSessionFactory" ...

  4. Centos75下samba搭建配置

    工作中,很经常需要把Linux服务器上的文件共享到windows上面,这时候需要在Linux服务器上安装samba套件. samba服务很好的实现了windows和linux之间的文件共享. 下面配置 ...

  5. SQL学习笔记四(补充-1)之MySQL单表查询

    阅读目录 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER BY 八 限制查询的记录 ...

  6. 微信小程序:全局配置app.json

    微信小程序:全局配置app.json 一.全局配置app.json app.json文件用来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. 以下是一个包 ...

  7. ubuntu18.04系统安装+基本环境配置【原创】

    平台信息:PC:ubuntu18.04.i5.七彩虹GTX1060显卡.固态硬盘.机械硬盘 作者:庄泽彬(欢迎转载,请注明作者) 说明:在原本的电脑买一个独立显卡,装上去之后,出了各种问题,虽然后面勉 ...

  8. P4 PI库安装

    repo:Github PI P4Runtime - a control plane framework and tools for the P4 programming language 这个是P4 ...

  9. Gym 101334E Exploring Pyramids(dp+乘法原理)

    http://codeforces.com/gym/101334 题意: 给出一棵多叉树,每个结点的任意两个子节点都有左右之分.从根结点开始,每次尽量往左走,走不通了就回溯,把遇到的字母顺次记录下来, ...

  10. 双击不能运行可执行的jar文件

    1.首先在命令行下运行jar包看文件是否报错(java -jar jar文件名称.jar)          如果程序中有System.out.println()语句,不想让其输出到控制台而保存到文件 ...