java多线程 -- 同步鎖
2017-03-30 23:54
113 查看
为了解决多线程安全问题
在 Java 5.0 之前,协调共享对象的访问时可以使用的机制只有 synchronized 和 volatile 。
Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能。
同步代码块;
同步方法。
ReentrantLock 实现了 Lock 接口,并提供了与synchronized 相同的互斥性和内存可见性。但相较于synchronized 提供了更高的处理锁的灵活性。
Lock使用方式:
相关API:
void lock() 获取锁。
void lockInterruptibly() 如果当前线程未被中断,则获取锁。
Condition newCondition() 返回绑定到此 Lock 实例的新 Condition 实例。
boolean tryLock() 仅在调用时锁为空闲状态才获取该锁。
boolean tryLock(long time, TimeUnit unit) 如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。
void unlock()释放锁。
不使用锁出现多线程安全问题demo:
看出现的问题(截取结果中一部分):
现在我们用Lock来进行处理:
看下结果(当然也是一部分),很完美解决多线程安全问题:
在 Java 5.0 之前,协调共享对象的访问时可以使用的机制只有 synchronized 和 volatile 。
Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能。
隐式锁
synchronized同步代码块;
同步方法。
显示锁 Lock
jdk 1.5 后:同步锁 Lock 需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁。ReentrantLock 实现了 Lock 接口,并提供了与synchronized 相同的互斥性和内存可见性。但相较于synchronized 提供了更高的处理锁的灵活性。
Lock使用方式:
Lock lock = new ReentrantLock(); lock.lock(); try { } finally { lock.unlock(); }
相关API:
void lock() 获取锁。
void lockInterruptibly() 如果当前线程未被中断,则获取锁。
Condition newCondition() 返回绑定到此 Lock 实例的新 Condition 实例。
boolean tryLock() 仅在调用时锁为空闲状态才获取该锁。
boolean tryLock(long time, TimeUnit unit) 如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。
void unlock()释放锁。
不使用锁出现多线程安全问题demo:
package com.company; public class TestLock { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(ticket, "1号窗口").start(); new Thread(ticket, "2号窗口").start(); new Thread(ticket, "3号窗口").start(); } } class Ticket implements Runnable{ private int tick = 100; @Override public void run() { while(true){ if(tick > 0){ try { Thread.sleep(200); } catch (InterruptedException e) { } System.out.println(Thread.currentThread().getName() + " 完成售票,余票为:" + --tick); } } } }
看出现的问题(截取结果中一部分):
3号窗口 完成售票,余票为:10 1号窗口 完成售票,余票为:8 2号窗口 完成售票,余票为:8 3号窗口 完成售票,余票为:8 2号窗口 完成售票,余票为:7 1号窗口 完成售票,余票为:7 3号窗口 完成售票,余票为:7 1号窗口 完成售票,余票为:6 2号窗口 完成售票,余票为:5 3号窗口 完成售票,余票为:4 3号窗口 完成售票,余票为:3 1号窗口 完成售票,余票为:3 2号窗口 完成售票,余票为:3 3号窗口 完成售票,余票为:2 1号窗口 完成售票,余票为:0 2号窗口 完成售票,余票为:1
现在我们用Lock来进行处理:
package com.company; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class TestLock { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(ticket, "1号窗口").start(); new Thread(ticket, "2号窗口").start(); new Thread(ticket, "3号窗口").start(); } } class Ticket implements Runnable { private int tick = 100; private Lock lock = new ReentrantLock(); @Override public void run() { while (true) { try { lock.lock(); if (tick > 0) { try { Thread.sleep(200); } catch (InterruptedException e) { } System.out.println(Thread.currentThread().getName() + " 完成售票,余票为:" + --tick); } } finally { lock.unlock(); } } } }
看下结果(当然也是一部分),很完美解决多线程安全问题:
2号窗口 完成售票,余票为:20 2号窗口 完成售票,余票为:19 2号窗口 完成售票,余票为:18 2号窗口 完成售票,余票为:17 2号窗口 完成售票,余票为:16 2号窗口 完成售票,余票为:15 2号窗口 完成售票,余票为:14 2号窗口 完成售票,余票为:13 2号窗口 完成售票,余票为:12 2号窗口 完成售票,余票为:11 2号窗口 完成售票,余票为:10 2号窗口 完成售票,余票为:9 2号窗口 完成售票,余票为:8 2号窗口 完成售票,余票为:7 2号窗口 完成售票,余票为:6 2号窗口 完成售票,余票为:5 2号窗口 完成售票,余票为:4 2号窗口 完成售票,余票为:3 2号窗口 完成售票,余票为:2 2号窗口 完成售票,余票为:1 2号窗口 完成售票,余票为:0
相关文章推荐
- 彻底明白Java的多线程-实现多线程及线程的同步
- 菜鸟课堂:详解Java多线程开发中的数据同步
- Java多线程 同步 锁 条件对象
- java 多线程、线程池及同步
- java多线程实现火车售票系统 以及java中的同步的实现 同步块 和同步方法同时 同步
- java多线程编码,顺序执行(同步)
- 初学Java多线程:使用Synchronized关键字同步类方法
- java基础之:多线程实现/启动/状态+同步+线程池
- java(多线程)实现高性能数据同步
- 2011-09-07 java多线程临界资源同步和调度问题,遇到困难加锁和解锁问题
- 详解Java多线程开发中的数据同步
- 浅谈Java多线程的同步问题
- 浅谈Java多线程的同步问题
- java多线程学习2-同步
- java多线程数据同步
- IBM Java多线程 - 5.同步详细信息
- 浅谈Java多线程的同步问题
- 浅谈Java多线程的同步问题
- Java多线程编程总结笔记——六线程的同步与锁
- java中多线程 内存模型和数据同步的一些要点