JAVA线程同步
来源:互联网 发布:床上用品在哪买 知乎 编辑:程序博客网 时间:2024/06/05 16:02
**
1. 什么是线程同步?
**
当多个线程共同访问同一资源时,会引发问题,所以需要线程同步来保证对资源的访问有序进行
例如:
class Toilet implements Runnable{ //记录可用的厕所数目 private int toilet = 1; public void run() { if(toilet>0) { toilet--; System.out.println(Thread.currentThread().getName()+"在厕所,别人不要进来"); } toilet++; System.out.println(Thread.currentThread().getName()+"从厕所出来了,别人可以进来"); }}public class Hello{ public static void main(String []args) { Toilet t = new Toilet(); for(int i =0;i<10;i++) { new Thread(t,i+"").start(); } }}
输出:
0在厕所,别人不要进来0从厕所出来了,别人可以进来1在厕所,别人不要进来1从厕所出来了,别人可以进来3在厕所,别人不要进来3从厕所出来了,别人可以进来2在厕所,别人不要进来2从厕所出来了,别人可以进来4在厕所,别人不要进来4从厕所出来了,别人可以进来5在厕所,别人不要进来5从厕所出来了,别人可以进来6在厕所,别人不要进来 //6还没出来,7就进去了,这显然不合理7在厕所,别人不要进来7从厕所出来了,别人可以进来6从厕所出来了,别人可以进来9在厕所,别人不要进来8在厕所,别人不要进来8从厕所出来了,别人可以进来9从厕所出来了,别人可以进来
以上显然不合理,线程对资源的使用很随意,当多个线程对同一资源进行修改的时候,会照成混乱。
2. JAVA中线程同步的方式
1. 采用synchronized关键字定义代码块
synchronized (obj){
…
代码
}
其中obj是同步监视器,一般将可能被多个线程使用的共享资源充当同步监视器,任何时刻只可能有一个线程能够访问同步监视器,当代码执行完之后才会释放同步监视器。
以下情况会释放同步监视器
- 同步方法、同步代码块执行完毕
- 同步方法、同步代码中遇到return、break
- 出现Error、Exception导致异常结束
- 当前程序执行了同步监视器的wait方法
以下情况不会释放同步监视器
- 当前程序调用Thread.sleep、Thread.yield方法,暂停当前方法的执行
- 其他线程调用当前线程的suspend方法将当前线程挂起
class Toilet implements Runnable{ //记录可用的厕所数目 private int toilet = 1; public void run() { synchronized(this) { //当前的对象 if(toilet>0) { toilet--; System.out.println(Thread.currentThread().getName()+"在厕所,别人不要进来"); } toilet++; System.out.println(Thread.currentThread().getName()+"从厕所出来了,别人可以进来"); } }}public class Hello{ public static void main(String []args) { Toilet t = new Toilet(); for(int i =0;i<10;i++) { new Thread(t,i+"").start(); } }}
输出:
0在厕所,别人不要进来0从厕所出来了,别人可以进来1在厕所,别人不要进来1从厕所出来了,别人可以进来2在厕所,别人不要进来2从厕所出来了,别人可以进来3在厕所,别人不要进来3从厕所出来了,别人可以进来4在厕所,别人不要进来4从厕所出来了,别人可以进来5在厕所,别人不要进来5从厕所出来了,别人可以进来6在厕所,别人不要进来6从厕所出来了,别人可以进来8在厕所,别人不要进来8从厕所出来了,别人可以进来7在厕所,别人不要进来7从厕所出来了,别人可以进来9在厕所,别人不要进来9从厕所出来了,别人可以进来
一切正常了
2.采用synchronized关键字定义方法
class Toilet implements Runnable{ //记录可用的厕所数目 private int toilet = 1; public synchronized void run() { //synchronized应该放在void之前 if(toilet>0) { toilet--; System.out.println(Thread.currentThread().getName()+"在厕所,别人不要进来"); } toilet++; System.out.println(Thread.currentThread().getName()+"从厕所出来了,别人可以进来"); }}public class Hello{ public static void main(String []args) { Toilet t = new Toilet(); for(int i =0;i<10;i++) { new Thread(t,i+"").start(); } }}
输出:
0在厕所,别人不要进来0从厕所出来了,别人可以进来3在厕所,别人不要进来3从厕所出来了,别人可以进来1在厕所,别人不要进来1从厕所出来了,别人可以进来2在厕所,别人不要进来2从厕所出来了,别人可以进来4在厕所,别人不要进来4从厕所出来了,别人可以进来5在厕所,别人不要进来5从厕所出来了,别人可以进来8在厕所,别人不要进来8从厕所出来了,别人可以进来6在厕所,别人不要进来6从厕所出来了,别人可以进来9在厕所,别人不要进来9从厕所出来了,别人可以进来7在厕所,别人不要进来7从厕所出来了,别人可以进来
一切也正常。
3.采用同步锁Lock来控制线程同步
Lock是JAVA.util.concurrent.locks里的接口
一般使用ReentrantLock(可重入锁)类。
例如:
class Toilet implements Runnable{ private final ReentrantLock lock = new ReentrantLock(); public void run() { lock.lock(); //上锁 try { System.out.println(Thread.currentThread().getName()+"在厕所,别人不要进来"); System.out.println(Thread.currentThread().getName()+"出来了,别人可以进去"); } finally { lock.unlock(); //释放锁 } }}public class Hello{ public static void main(String []args) { Toilet t = new Toilet(); for(int i =0;i<10;i++) { new Thread(t,i+"").start(); } }}
使用线程同步会使程序运行速度变慢,所以只有需要同步的地方才去使用同步
阅读全文
0 0
- JAVA线程-JAVA同步
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步块
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步块
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步块
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步块
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步块
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步块
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步块
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- TensorFlow学习笔记(二):TensorFlow实现线性回归模型
- 剑指offer(算法和数据操作篇)
- codeforces 120F Spiders
- 算法基础(转载)
- Sublime Text 3技巧:支持GB2312和GBK编码
- JAVA线程同步
- ICCV2017论文分类
- jmap -heap 命令
- 多线程 批处理 数据导入工具 Java
- STL常用算法: distance实现,count_if算法实现,bind2nd的使用..
- 阶段性困惑_1
- 禅道使用方法-测试使用
- 进程
- 用UML建模开发嵌入式软件