public interface Lock ,通常我们这样来创建锁对象:
Lock lock = new ReentrantLock();
package com.spider.java;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* @author yangcq
* @desctiption Java中的锁
*
*/
public class LockLearning {
// 定义一个全局变量,账户余额
private static int account_balance = 1000000000;
public static void main(String[] args) {
// 创建可重入锁对象lock
Lock lock = new ReentrantLock();
// 在执行一段代码之前获取锁
lock.lock();
// 执行代码,修改余额的值,这里可以是我们项目中任何一个需要加锁的操作
updateAccountBalance(account_balance);
// 在执行一段代码之后释放锁
lock.unlock();
}
private static int updateAccountBalance(Integer account_balance){
return account_balance - 1000;
}
}
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
/**
* Returns a new {@link Condition} instance that is bound to this
* {@code Lock} instance.
*
* Before waiting on the condition the lock must be held by the
* current thread.
* A call to {@link Condition#await()} will atomically release the lock
* before waiting and re-acquire the lock before the wait returns.
*
*
Implementation Considerations
*
*
The exact operation of the {@link Condition} instance depends on
* the {@code Lock} implementation and must be documented by that
* implementation.
*
* @return A new {@link Condition} instance for this {@code Lock} instance
* @throws UnsupportedOperationException if this {@code Lock}
* implementation does not support conditions
*/
package com.spider.java;
import java.util.logging.Logger;
/**
*
* @author yangcq
* @description synchronized关键字的使用方法
*
*/
public class SynchronizedLearning {
static Logger logger = Logger.getAnonymousLogger();
public static void main(String[] args) {
/**
* synchronized关键字实现同步有2种方式,同步方法和同步块
*/
// 同步块
synchronized(SynchronizedLearning.class){
logger.info("我是同步块...");
}
synchronizedMethod();
}
// 同步方法
public static synchronized void synchronizedMethod(){
logger.info("我是同步方法...");
}
}
package com.spider.java;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
*
* @author yangcq
* @description 自定义锁 - 独占锁UserDefineLock,也就是在同一时刻,只有一个线程可以获得锁
*
*/
public class UserDefineLock implements Lock {
// 使用队列同步器AQS以后,我们只需要将锁的操作代理到自定义的同步器上就可以了
private final SynchronizerDefine synchronizerDefine = new SynchronizerDefine();
@Override
public void lock() {
synchronizerDefine.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
synchronizerDefine.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return synchronizerDefine.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return synchronizerDefine.tryAcquireNanos(1, unit.toNanos(time));
}
@Override
public void unlock() {
synchronizerDefine.release(1);
}
@Override
public Condition newCondition() {
return synchronizerDefine.newCondition();
}
public boolean hasQueueThreads(){
return synchronizerDefine.hasQueuedThreads();
}
public boolean isLocked(){
return synchronizerDefine.isHeldExclusively();
}
// 静态内部类,自定义同步器
private static class SynchronizerDefine extends AbstractQueuedSynchronizer{
/**
*
*/
private static final long serialVersionUID = -5572420543429760541L;
// 判断当前锁是否处于占用状态
protected boolean isHeldExclusively(){
return getState() == 1;
}
// 当状态为0时,获取锁
public boolean tryAcquire(int acquires){
if(compareAndSetState(0,1)){
// 官方注释:Sets the thread that currently owns exclusive access.
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
// 释放锁之后,将状态设置为0
protected boolean tryRelease(int releases){
if(getState() == 0){
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);
setState(0);
return true;
}
// 返回一个Condition,每个Condition都包含一个condition实例
Condition newCondition(){
return new ConditionObject();
}
}
}
package com.spider.java;
import java.util.concurrent.locks.Lock;
import java.util.logging.Logger;
/**
*
* @author yangcq
* @description 队列同步器AbstractQueuedSynchronizer
* @description public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer
*
*/
public class AbstarctQueueSynchronizerLearning {
// 打印logger日志
static Logger logger = Logger.getAnonymousLogger();
// 主方法
public static void main(String[] args){
test();
}
public static void test(){
final Lock lock = new UserDefineLock();
class ProductThread extends Thread{
public void run(){
while(true){
lock.lock();
try{
sleep(1500);
logger.info(Thread.currentThread().getName());
sleep(1500);
}
catch(Exception e){
lock.unlock();
}
finally{
lock.unlock();
}
}
}
}
// 启动5个线程
for(int i=0;i<10;i++){
ProductThread productThread = new ProductThread();
productThread.setDaemon(true);
productThread.start();
}
// 每隔1.5秒 打印 -----------
for(int i=0;i<10;i++){
try {
ProductThread.sleep(1500);
logger.info("-----------");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2016-7-31 1:44:04 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:04 com.spider.java.AbstarctQueueSynchronizerLearning$1ProductThread run
信息: Thread-1
2016-7-31 1:44:06 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:07 com.spider.java.AbstarctQueueSynchronizerLearning$1ProductThread run
信息: Thread-1
2016-7-31 1:44:07 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:09 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:10 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:10 com.spider.java.AbstarctQueueSynchronizerLearning$1ProductThread run
信息: Thread-1
2016-7-31 1:44:12 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:13 com.spider.java.AbstarctQueueSynchronizerLearning$1ProductThread run
信息: Thread-3
2016-7-31 1:44:13 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:15 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:16 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:44:16 com.spider.java.AbstarctQueueSynchronizerLearning$1ProductThread run
信息: Thread-3
2016-7-31 1:44:18 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:58:50 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:58:51 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:58:53 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:58:54 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:58:56 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:58:57 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:58:59 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:59:00 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:59:02 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
2016-7-31 1:59:03 com.spider.java.AbstarctQueueSynchronizerLearning test
信息: -----------
/**
* Performs non-fair tryLock. tryAcquire is
* implemented in subclasses, but both need nonfair
* try for trylock method.
*/
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
Lock lock = new ReentrantLock(true); // 以公平的方式获取锁
Lock lock = new ReentrantLock(false); // 以非公平的方式获取锁
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = (fair)? new FairSync() : new NonfairSync();
}
/**
* Sync object for fair locks 以公平的方式获取锁
*/
final static class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
// 区别就在于这里,以公平方式获取锁时,会判断当前线程是不是
// 第一个请求获取该锁的线程。
if (isFirst(current) && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
/**
* Sync object for non-fair locks 以非公平的方式获取锁
*/
final static class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
// 非公平方式的方法实现nonfairTryAcquire
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable
/** Inner class providing readlock 读锁(内部类)*/
private final ReentrantReadWriteLock.ReadLock readerLock;
/** Inner class providing writelock 写锁(内部类)*/
private final ReentrantReadWriteLock.WriteLock writerLock;
/** Performs all synchronization mechanics 队列同步器AQS实现类*/
private final Sync sync;
public static class ReadLock implements Lock, java.io.Serializable // 读锁
public static class WriteLock implements Lock, java.io.Serializable // 写锁
public interface Condition {
void await() throws InterruptedException;
void awaitUninterruptibly();
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
boolean awaitUntil(Date deadline) throws InterruptedException;
void signal();
void signalAll();
}
package com.spider.java;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
/**
*
* @author yangcq
* @description Condition接口 + Lock 实现等待/通知模式
* @description 测试类 ConditionLearningTest
*
*/
public class ConditionLearning {
static Logger logger = Logger.getAnonymousLogger(); // 日志
Lock lock = new ReentrantLock();
Condition condition_get = lock.newCondition();
// 定义一个Map
Map map = new HashMap();
// 取值 -- 如果值为空,则等待...
public void conditionWait() throws InterruptedException{
map.put("yangcq", "");
lock.lock();
try{
while("".equals(map.get("yangcq"))){
logger.info("key 'yangcq' 为空,不能取值...");
condition_get.await();
}
logger.info("key 'yangcq' 的值为:" + map.get("yangcq"));
}
finally{
lock.unlock();
}
}
// 赋值 -- 赋值以后,有值了,唤醒
public void conditionSignal() throws InterruptedException{
map.put("yangcq", "1988");
lock.lock();
try{
if("".equals(map.get("yangcq"))){
logger.info("key 'yangcq' 为空,不能让其他方法从这里取值...");
}
else{
logger.info("key 'yangcq' 有值,可以唤醒取值的方法");
// 唤醒取值线程(消费者线程)
condition_get.signal();
}
}
finally{
lock.unlock();
}
}
}
package com.spider.java;
/**
*
* @author yangcq
* @description Condition接口 + Lock 实现等待/通知模式测试
*
*/
public class ConditionLearningTest {
// 创建ConditionLearning对象
static ConditionLearning conditionLearning = new ConditionLearning();
public static void main(String[] args) {
getValue(); // 初始值为空,消费者线程等待...
putValue(); // 生产者赋值以后,有值了,通知消费者线程,然后消费者线程唤醒
}
@SuppressWarnings("static-access")
public static void getValue(){
// 消费者线程
class ConsumerThread extends Thread{
public void run(){
try {
conditionLearning.conditionWait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ConsumerThread ConsumerThread = new ConsumerThread();
ConsumerThread.start();
try {
ConsumerThread.sleep(2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void putValue(){
// 生产者线程
class ProductThread extends Thread{
public void run(){
try {
conditionLearning.conditionSignal();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ProductThread ProductThread = new ProductThread();
ProductThread.start();
}
}