java线程池 synchronized_java多线程学习(二) 之 synchronized
在实现线程同步方法里,synchronized是java中最简单的方法。
官方解释:
The use of synchronized methods or statements provides access to the implicit monitor lock associated with every object, but forces all lock acquisition and
release to occur in a block-structured way
synchronized 的使用有同步方法,和同步代码块,它提供了对一个对象隐式监视器锁的访问,也就是说synchronized之所以能实现线程间同步,是通过获取对象的锁实现的,只是这个锁是隐式的,看不见的,默认java每个对象都有一个锁存在。还有之所以说synchronized是java中实现线程同步最简单的方法,是因为synchronized对锁的获取和释放是有限制的,必须是在一个方法或者一段代码块前后。
synchronized 有两种使用方法:
一种是修饰方法,修饰方法的时候,如果是修饰的普通方法,那就是获取这个类对应的实例的锁,如果是修饰的静态方法,那就是获取这个类的Class对象的锁。例如:
public MyObject{
public synchronized void print()
{
//TODO
}
public static synchronized void printStatic()
{
//TODO
}
}
MyObject my = new MyObject();
也就是说,一个线程在执行my.print()之前必须先获取my这个对象对应的隐式锁,在方法执行完之后自动释放。同样的一个线程在执行MyObject.printStatic()之前必须线获取MyObject.class这个对象的锁。如果对象的锁被别的线程占用,在调用方法的时候,线程就会等待在那里,直到别的线程释放锁为止。
另外一种方法是修饰代码块,表示在执行一块代码之前明确要求要获取哪个对象的锁,这种方法释放锁的标志是代码块执行结束,例如
public MyObject{
private MyLock mylock = new MyLock();
public void print1()
{
synchronized(this)
{
//todo;
}
}
public void print2()
{
synchronized(MyObject.class)
{
//todo;
}
}
public void print3()
{
synchronized(MyObject2.class)
{
//todo;
}
}
public void print4()
{
synchronized(mylock)
{
//todo;
}
}
}
代码已经很明确了,你可以以任何对象作为锁对象。需要说明的时,这里线程之间的同步,只是针对synchronized修饰过的代码,而且必须是锁对象是相同的,才会发生线程互斥,线程等待。对于没有synchronized或者锁对象不同的线程是不互斥的,是可以同步执行的。
例如第一种里的print方法和第二种里print1里的代码块都是锁的相应的对象,一个线程如果执行对象my.print()的时候,另外一个线程在调my.print1()的时候,就会堵塞在synchronized(this)的地方,直到my.print()执行结束,释放锁。
还有我们说的线程互斥,是指两个线程之间,如果是一个线程内部是可以重复获取一个锁的,自己不会和自己互斥的。也就是说synchronized可以嵌套:
public MyObject{
public void print1()
{
synchronized(this)
{
synchronized(this)
{
//todo;
}
}
}
}
当然,如果synchronized嵌套锁不同的对象,那就有可能发生线程之间死锁的问题,那就是另外一个话题了。
java线程池 synchronized_java多线程学习(二) 之 synchronized相关推荐
- Java线程池详解学习:ThreadPoolExecutor
Java线程池详解学习:ThreadPoolExecutor Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) - zhangpeterx的博客 在源码的目录java/util/ ...
- Java 线程池详解学习:FixedThreadPool,CachedThreadPool,ScheduledThreadPool...
Java常用的线程池有FixedThreadPool和CachedThreadPool,我们可以通过查看他们的源码来进行学习. Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) ...
- java线程池_Java多线程并发:线程基本方法+线程池原理+阻塞队列原理技术分享...
线程基本方法有哪些? 线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等. 线程等待(wait) 调用该方法的线程进入 WAITING 状态,只有等 ...
- Java线程池 - 问题驱动学习
Java线程池 本章内容: 1.问题驱动"Java线程池"学习 2.线程池的功能需求 3.实现Thread Pool模式 4.JUC Executors源码分析
- java定长池,java线程池源码学习
使用Executors创建线程池 Executor是一个工厂类,可以直接创建线程池,从最简单的定长线程池开始学习 public static ExecutorService newFixedThrea ...
- java线程池的使用学习
目录 1. 线程池的创建 2. 线程池的运行规则 3. 线程池的关闭 4. 线程池的使用场合 5. 线程池大小的设置 6 实现举例 1. 线程池的创建 线程池的创建使用ThreadPoolExecut ...
- java 线程等待队列_Java多线程学习(五)——等待通知机制
等待通知机制的实现 方法wait()的作用是使当前线程进行等待,wait()方法是Object类的方法,该方法用来将当前线程放到"预执行队列",并在wait()所在的代码处停止执行 ...
- java 线程起名字_java多线程学习三::::为什么要给线程起名字并且知道守护作用?...
为什么要会线程起名字呢? 你如果拿到一连串的Thread-01,Thead-02我想你应该会疯掉,看以下代码 package rs.thread.day0504; /** * @auther rs * ...
- JAVA线程池 之 Executors (二) 原理分析
一.线程池状态 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));private static final ...
最新文章
- 上古卷轴3晨风职业_上古卷轴3:晨风
- Google推出的新服务:Docs Spreadsheets
- java中appletviewer是什么意思_Java开发网 - 请教,appletviewer的问题
- P1433 吃奶酪(状压dp)
- Eclipse连接数据库MySQL以及一些有关数据库的知识
- Luogu P2463 [SDOI2008]Sandy的卡片
- MySQL:备份数据库脚本报错mysqldump: Couldn‘t execute ‘SELECT COLUMN_NAME****
- PostgreSQL 逻辑订阅 - 给业务架构带来了什么希望?
- 开发了一套python的七牛sdk
- 大型项目linux自动化版本发布脚本(shell)之tomcat、nginx服务脚本
- 企业选型数据库系统的五点建议
- 东南大学计算机考研数学教材,考东南大学计算机的看这里,双非学长逆袭!
- 网页游戏开发入门教程三(简单程序应用)
- 设计师最常用网站汇总
- 国产FPGA研究框架
- fromkeys()
- 为什么曾经优秀的老员工被辞退了?
- 【JAVA】GUI常用组件
- 手机html端悬浮球,大屏手机绝配!一款轻巧强大的悬浮球App
- melodic 奥比中光(orbbec)相机安装
热门文章
- 页面放在哪_思维制胜!PPT内容巨多的页面,这样排版更高大上
- python3 携程_多任务(3):协程
- charles 中文_抓包工具--charles(青花瓷)及获取AppStore数据包
- 虚拟专题:知识图谱 | 频谱知识图谱:面向未来频谱管理的智能引擎
- 【软件测试】软件测试与概率
- 【数据结构与算法】二叉查找树的Java实现
- 坑爹的Java除法取整(记洛谷P5709题WA的经历,Java语言描述)
- 【Java】自编时间相关常用函数
- 【计算机科学基础】ASCII码表知识总结
- Fish Redux 使用指南