好记性不如烂笔头~~

并发编程中synchronized关键字的地位很重要,很多人都称它为重量级锁。利用synchronized实现同步的基础:Java中每一个对象都可以作为锁。具体表现为以下三种形式。

(1)对于普通同步方法,锁是当前实例对象。

(2)对于静态同步方法,锁是当前类的Class对象。

(3)对于同步方法块,锁是synchronized括号里配置的对象。

一、普通同步方法

使用synchronized关键字修饰一个普通方法,锁住的是当前实例的对象。当synchronized锁住该对象后,别的线程如果也想拿到这个对象的锁,就必须等待这个线程执行完成释放锁,才能再次给对象加锁,这样才达到线程同步的目的。

实验一

class Synch{

public synchronized void test1(){

System.out.println("test1开始");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("test1结束");

}

public synchronized void test2(){

System.out.println("test2开始");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("test2结束");

}

}

public class SyncTest extends Synch{

public static void main(String args[]){

Synch s=new Synch();

Thread t1=new Thread(new Runnable(){

@Override

public void run() {

// TODO Auto-generated method stub

s.test1();

}

});

Thread t2=new Thread(new Runnable(){

@Override

public void run() {

// TODO Auto-generated method stub

s.test2();

}});

t1.start();

t2.start();

}

}

实验结果:

分析上述代码,类Synch中有两个普通同步方法test1和test2.在主函数中实现了该类,同时定义两个thread线程,run方法中分别调用类Synch的方法。synchronized实现的普通同步方法,锁住的是当前实例对象,即Synch类对象。由于两个线程是调用的同一个对象中的同步方法,所以只有一个线程释放该对象的锁,另一个线程才能调用。

实验二

class Sync{

public synchronized void test(String threadname){

System.out.println(threadname+"开始");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(threadname+"结束");

}

}

class MyThread extends Thread{

public int i;

public MyThread(int i){

this.i=i;

}

Sync s=new Sync();

public void run(){

//Sync sync=new Sync();

s.test("Thread"+i);

}

}

public class SynTest {

public static void main(String args[]){

for(int i=0;i<3;i++){

Thread thread=new MyThread(i);

thread.start();

}

}

}

实验结果:

上述代码,每个线程中都new了一个Sync类的对象,也就是产生了三个Sync对象,由于不是同一个对象,所以可以多线程同时运行synchronized方法。

二、静态同步方法

对于静态同步方法,锁是当前类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。只有一个线程结束后,另一个线程才能获得锁。

实验三

class Synch{

public static synchronized void test1(){

System.out.println("test1开始");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("test1结束");

}

public static synchronized void test2(){

System.out.println("test2开始");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("test2结束");

}

}

public class SyncTest extends Synch{

public static void main(String args[]){

Synch s1=new Synch();

Synch s2=new Synch();

Thread t1=new Thread(new Runnable(){

@Override

public void run() {

// TODO Auto-generated method stub

s1.test1();

}

});

Thread t2=new Thread(new Runnable(){

@Override

public void run() {

// TODO Auto-generated method stub

s2.test2();

}});

t1.start();

t2.start();

}

}

实验结果:

三、同步方法块

这部分更好理解,锁住的是synchronized括号里配置的对象。

实验四

public class Threadtest implements Runnable{

@Override

public void run() {

// TODO Auto-generated method stub

synchronized(this){

for (int i = 0; i < 5; i++) {

System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);

}

}

}

public static void main(String[] args) {

Threadtest t1 = new Threadtest();

Thread ta = new Thread(t1, "A");

Thread tb = new Thread(t1, "B");

ta.start();

tb.start();

}

}

运行结果:

上述代码,synchronized代码块括号里配置的对象是this,同一个对象,所以只有一个线程访问该代码块结束后,释放锁,另一个线程才能访问该代码块。

需要注意的是,其他线程可以访问非synchronized(this)同步代码。如下代码

实验五

class MyThread1{

public void test1(){

synchronized(this){

System.out.println("同步代码块-test1开始");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("同步代码块-test1结束");

}

}

public void test2(){

try {

Thread.sleep(500);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("非同步代码块-test2");

}

}

public class ThreadTest1 {

public static void main(String args[]){

MyThread1 t=new MyThread1();

Thread t1=new Thread(new Runnable(){

@Override

public void run() {

// TODO Auto-generated method stub

t.test1();

}

});

Thread t2=new Thread(new Runnable(){

@Override

public void run() {

// TODO Auto-generated method stub

t.test2();

}

});

t1.start();

t2.start();

}

}

运行结果:

synchronized括号里配置的是this,只是对这一段代码进行了加锁,同一个对象,只有一个线程能访问该代码块,释放锁之后,其他线程才可以访问,但是并不影响其他线程访问非同步代码块。

同步代码块,同步方法的实现~~简单理解

对于同步代码块是使用monitorenter、monitorexit指令实现的。每个对象都有一个监视器锁(monitor),当monitor被占用时,就会处于锁定状态。

线程执行monitorenter指令尝试获取monitor的所有权。

如果monitor的进入数为0,则该线程进入monitor,并将进入数设置为1

如果该线程已经占有了该monitor,重新进入,进入数也要+1

如果其他线程占用了monitor,则该线程进入阻塞状态,知道进入数为0

对于同步方法,常量池中多了ACC_SYNCHRONIZED标识符,方法调用时,先检查该标识符的访问标志,如果设置了,则进程先获取monitor,获取成功后才能执行方法体,方法执行完之后再释放monitor。

java synchronized_Java中synchronized关键字理解相关推荐

  1. java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题

    先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...

  2. Java进阶1. Synchronized 关键字

    Java进阶1. Synchronized 关键字 20131025 1.关于synchronized的简介: Synchronized 关键字代表对这个方法加锁,相当于不管那一个线程,运行到这个方法 ...

  3. 关于java多态中覆盖的理解

    在前面一篇文章中,我已经介绍了关于java多态中重载的理解与规则 所以这篇文章主要介绍多态中的覆盖机制. 首先重载与覆盖除了表现方式不同之外,还有运行时间上的不同,重载是在编译期间就已经可以确定好调用 ...

  4. Java类中this关键字和static关键字的用法详解

    今天给大家总结介绍一下Java类中this关键字和static关键字的用法. 文章目录 this关键字用法: 1:修饰属性,表示调用类中的成员变量 2:this修饰方法 3:this表示当前对象的引用 ...

  5. Java中 synchronized 关键字的理解

    synchronized 关键字的理解 在Java中,synchronized 是一个重量级的控制并发的关键字. 这个关键字可以保证并发过程所必须的"原子性","可见性& ...

  6. java同步关键字_Java中synchronized关键字修饰方法同步的用法详解

    Java的最基本的同步方式,即使用synchronized关键字来控制一个方法的并发访问. 每一个用synchronized关键字声明的方法都是临界区.在Java中,同一个对象的临界区,在同一时间只有 ...

  7. Java 并发编程—Synchronized关键字

    原文作者:liuxiaopeng 原文地址:Java并发编程:Synchronized及其实现原理 目录 一.Synchronized的基本使用 二.Synchronized 原理 三.运行结果解释 ...

  8. 你用或者不用:线程中synchronized关键字使用总结

    感谢张龙老师! Synchronized关键字,同步的, synchronized关键字可以修饰方法,还有静态代码块(static block) Java中的每一个对象都有一把锁(lock),只是平时 ...

  9. synchronized关键字理解

    引入 需求 先看一个简单的需求 我们现在模拟一下银行的叫号机生产号码(号码范围为1~100),假设我们现在有四个取号机,要求每个人取得到号码不重复,并且不能有遗漏,很多人就很快的可以写出下面的代码 代 ...

最新文章

  1. 仿QQ空间用一个tableview显示多种自定义cell
  2. lgg6 android 9,【LGG6评测】18:9奇葩比例没采用骁龙835 LG G6解析_LG G6_手机评测-中关村在线...
  3. 如果没有杜撰,可还有历史?
  4. 蓝牙管理软件_Mac蓝牙检测软件----BlueSense
  5. 神经网络 | BP神经网络-数字识别(附源代码)
  6. boost::math模块计算贝塞尔函数的零点的测试程序
  7. jquery 字符串查找_Python Appium 库IOS特有元素查找API介绍
  8. [c语言]运算符的优先级与结合性
  9. c++ 工厂模式_大连中山融雪剂工厂自营工厂批发
  10. 你第一次去丈母娘家时发生了哪些趣事?
  11. SQL 引擎如何把语句转换为一个抽象语法树?
  12. 蓝桥杯B组省赛预赛第一题2013(高斯日记)
  13. 数据结构学习-Java实现复数类
  14. mapxtreme 查找指定位置的图元
  15. 全国计算机将文件属性隐藏,一键玩转隐藏属性文件
  16. java乘法口诀编程题_【视频+图文】Java经典基础练习题(二)输出9*9乘法口诀表...
  17. 银行账户管理系统(一)
  18. Oracle索引的维护
  19. 英雄帖:乌镇巴比特加速器潜力项目DemoDay,虚位以待
  20. 运动会加油稿计算机学院150字,大学运动会经典加油稿150字左右2018

热门文章

  1. 华东师范大学计算机考研信息汇总
  2. 最新前端开发面试题集合(非常全面)
  3. 中央农村工作会议释放重要信号,AI 技术助力农业的十种路径,未来可期
  4. 手机误删的照片怎么恢复?恢复方法分享
  5. 程序员开发效率神器汇总!
  6. 多语言应用性能监控系统:Elastic APM
  7. 举一反三快速学会如何全面超频
  8. 微信发送图文消息,查看图文media_id
  9. 主板显卡服务器维修,显卡无显示怎么维修 显卡无显示解决方法【详细介绍】...
  10. python绘制分形图基础_python绘制分形图