一、简单的锁知识

关于内置锁

Java具有通过synchronized关键字实现的内置锁,内置锁获得锁和释放锁是隐式的,进入synchronized修饰的代码就获得锁,走出相应的代码就释放锁。

java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,直到线程B释放这个锁,如果B线程不释放这个锁,那么A线程将永远等待下去。

对象锁和类锁

这其实也是Java的内置锁。

对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的。

二、synchronized所代表的内置锁的使用方法

1.synchronized修饰普通方法

class A {
  public synchronized void test() {   }
  public void test2() {   }
}

这种情况下,用的其实是这个方法所在的类的实例对象的锁,也就是A的一个实例的对象锁。意思是,比如A a = new A();,如果两个线程同时调用了a的这个test方法,那么先调用的那个线程,就先拿到这个实例a的对象锁,而另一个线程呢,就要只能等拿到a锁的那个线程运行完这个test方法后,把锁放了,然后再抢到实例a对象锁后才能运行这个test方法。

注意,虽然说锁的是这个方法所在类的实例对象,但其他线程是可以自由访问这个对象中的非同步方法的。比如这个A类中还有另一个方法叫test2,是不同步的,那么即使线程1抢到对象锁,在进行test方法中,线程2是可以同时访问运行test2方法的,因为这是个不同步的方法。

2.同步块(对象锁)

class A {
public void test() {
synchronized(this) {//也可以锁其他对象
xxx
}
}
}

这个锁的也是某个对象的实例。

3.类锁(同步块)

class A {
public void test() {
synchronized(A.class) {
xxx
}
}
}

其实一鬼样的,就是之前锁的是实例对象,现在锁的是一个类,或者说是一个类对象(Class Object),类锁只是抽象出来的一个概念,而且因为类的Class Object或者说加载的类信息只有一个,所有抽象出来个类锁。

4.类锁之——修饰static方法

class A {
public static synchronized void test() { }
}

synchronized修饰static的方法的时候,也是类锁,锁的也是这个类,或者说是这个类的Class Object,因为静态方法是所有对象实例共有的,一个类只有一个,static方法也是在类加载的时候就加载了,所以synchronized修饰static方法的时候,锁也是唯一的,所以也是类锁哦。

三、关于类锁和对象锁的注意:

看下这个例子:

public class TestSynchronized
{
public synchronized void test1()
{
int i = 5;
while( i-- > 0)
{
System.out.println(Thread.currentThread().getName() + " : " + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}
public static synchronized void test2()
{
int i = 5;
while( i-- > 0)
{
System.out.println(Thread.currentThread().getName() + " : " + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}
public static void main(String[] args)
{
final TestSynchronized myt2 = new TestSynchronized();
Thread test1 = new Thread( new Runnable() { public void run() { myt2.test1(); } }, "test1" );
Thread test2 = new Thread( new Runnable() { public void run() { TestSynchronized.test2(); } }, "test2" );
test1.start();
test2.start();
// TestRunnable tr=new TestRunnable();
// Thread test3=new Thread(tr);
// test3.start();
}
} test1 : 4
test2 : 4
test1 : 3
test2 : 3
test2 : 2
test1 : 2
test2 : 1
test1 : 1
test1 : 0
test2 : 0

上面代码synchronized同时修饰静态方法和实例方法,但是运行结果是交替进行的,这证明了类锁和对象锁是两个不一样的锁,控制着不同的区域,它们是互不干扰的。同样,线程获得对象锁的同时,也可以获得该类锁,即同时获得两个锁,这是允许的。

其实这个也很显然,一个锁的是类的实例,一个是类的Class Object,这两个都不是一个东西hh。

四、synchronized中条件判断用while而不是用if

例子见这篇文章:https://www.cnblogs.com/heyboom/p/9147469.html

Java内置锁和简单用法的更多相关文章

  1. Java内置锁的简单认识

    多线程开发离不开锁机制,现在的Java语言中,提供了2种锁,一种是语言特性提供的内置锁,还有一种是 java.util.concurrent.locks 包中的锁,这篇文章简单整理一下内置锁的知识点. ...

  2. 深入理解Java内置锁和显式锁

    synchronized and Reentrantlock 多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两 ...

  3. 深入理解java内置锁(synchronized)和显式锁(ReentrantLock)

    多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两种同步方式.显式锁是JDK1.5引入的,这两种锁有什么异同呢? ...

  4. Java内置锁synchronized的实现原理

    简述Java中每个对象都可以用来实现一个同步的锁,这些锁被称为内置锁(Intrinsic Lock)或监视器锁(Monitor Lock). 具体表现形式如下: 1.普通同步方法,锁的是当前实例对象 ...

  5. Java内置锁synchronized的实现原理及应用(三)

    简述 Java中每个对象都可以用来实现一个同步的锁,这些锁被称为内置锁(Intrinsic Lock)或监视器锁(Monitor Lock). 具体表现形式如下: 1.普通同步方法,锁的是当前实例对象 ...

  6. Java 内置锁 重入问题

    阅读<Java并发编程实战>,遇到了一个问题 代码如下 /** * @auther draymonder */ public class Widget { public synchroni ...

  7. java内置锁实现锁住代码块方案(同一个对象或锁住整个类.class)

    我们看一个例子: class Demo { public synchronized void test() { System.out.println("test方法开始执行,当前线程为:&q ...

  8. Java内置锁synchronized的可重入性

    学习自 https://blog.csdn.net/aigoogle/article/details/29893667 对我很有帮助 感谢作者

  9. 七 内置锁 wait notify notifyall; 显示锁 ReentrantLock

    Object中对内置锁进行操作的一些方法: Java内置锁通过synchronized关键字使用,使用其修饰方法或者代码块,就能保证方法或者代码块以同步方式执行. 内置锁使用起来非常方便,不需要显式的 ...

随机推荐

  1. C语言中的排序算法--冒泡排序,选择排序,希尔排序

    冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...

  2. codeforces A. Fox and Box Accumulation 解题报告

    题目链接:http://codeforces.com/problemset/problem/388/A 题目意思:有 n 个 boxes,每个box 有相同的 size 和 weight,但是stre ...

  3. 万亿级日志与行为数据存储查询技术剖析(续)——Tindex是改造的lucene和druid

    五.Tindex 数果智能根据开源的方案自研了一套数据存储的解决方案,该方案的索引层通过改造Lucene实现,数据查询和索引写入框架通过扩展Druid实现.既保证了数据的实时性和指标自由定义的问题,又 ...

  4. plsql导入cvs 时提示missing right parenthesis

    删除自动生成的时间格式值,如:SQL function框里自动生成的值

  5. MAC 安装phantomjs

    step1:下载压缩包http://phantomjs.org/ step2:解压缩,我是解压缩到/Users/gxy/software step3:写入配置路径,vi ~/.bash_profile ...

  6. 「LuoguP3808」 【模板】AC自动机(简单版)

    题目背景 通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. ...

  7. No result defined for action cn.crm.action.LinkManAction and result input

    这是struts2的一个拦截器报的错误,当你的form中的数据有问题,比如说<input type="text" name="receiverLoginID&quo ...

  8. MTK OTG 流程

    一.注册mt_usb驱动 kernel-3.18/drivers/misc/mediatek/usb20/mt6735/usb20.c static int __init usb20_init(voi ...

  9. 机器学习之K-means算法

    前言            以下内容是个人学习之后的感悟,转载请注明出处~ 简介 在之前发表的线性回归.逻辑回归.神经网络.SVM支持向量机等算法都是监督学习算法,需要样本进行训练,且 样本的类别是知 ...

  10. css3单位em,rem,px,vw,vh等

    昨天发现了个好用的方法去设置手机端的rem单位,在这里记录下. html{ font-size:calc(100vw/7.5);} 这是按照750的设计稿(也就是iphone6的设计稿). 100vw ...