一、使用锁实现同步
二、和synchronized相比基于Lock接口及其实现类,Lock接口及其实现类如下:
1、支持更灵活的代码块结构
使用synchronized关键字时,只能在同一个synchronized块结构中获取和释放控制,Lock允许控制的获取和释放不在同一个块结构中
2、Lock接口功能更强大
3、Lock允许分离读和写操作,允许多个读线程和只有一个写线程
4、Lock具有更好的性能
三、模拟打印队列
package com.concurrent.threadSynchronize; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 模拟打印队列 * * @author Nicholas * */ public class PrintQueue { // 声明一个锁对象,调用ReentrantLock实例化 private final Lock queueLock = new ReentrantLock(); public void printJob(Object documentObject) { // 调用lock方法获取对锁对象的控制 queueLock.lock(); try { Long duration = (long) (Math.random() * 10000); System.out.println(Thread.currentThread().getName() + " : PrintQueue : Printing a Job during " + (duration / 1000) + " seconds"); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); }finally { //释放锁 queueLock.unlock(); } } }
package com.concurrent.threadSynchronize; /** * 打印工作类 * * @author Nicholas * */ public class Job implements Runnable { private PrintQueue printQueue; public Job(PrintQueue printQueue) { this.printQueue = printQueue; } @Override public void run() { System.out.println("Going to print a document " + Thread.currentThread().getName()); printQueue.printJob(new Object()); System.out.println("The document has been printed " + Thread.currentThread().getName()); } }
package com.concurrent.threadSynchronize; public class Main { public static void main(String[] args) { //共享的打印队列对象 PrintQueue printQueue = new PrintQueue(); Thread[] threads = new Thread[10]; for (int i = 0; i < 10; i++) { threads[i] = new Thread(new Job(printQueue), "Thread " + i); } for (int i = 0; i < threads.length; i++) { threads[i].start(); } } }
输出:
四、Lock原理Going to print a document Thread 0 Going to print a document Thread 3 Going to print a document Thread 1 Going to print a document Thread 2 Going to print a document Thread 4 Thread 0 : PrintQueue : Printing a Job during 6 seconds Going to print a document Thread 5 Going to print a document Thread 6 Going to print a document Thread 7 Going to print a document Thread 8 Going to print a document Thread 9 The document has been printed Thread 0 Thread 3 : PrintQueue : Printing a Job during 8 seconds The document has been printed Thread 3 Thread 1 : PrintQueue : Printing a Job during 8 seconds The document has been printed Thread 1 Thread 2 : PrintQueue : Printing a Job during 2 seconds The document has been printed Thread 2 Thread 4 : PrintQueue : Printing a Job during 9 seconds The document has been printed Thread 4 Thread 5 : PrintQueue : Printing a Job during 5 seconds The document has been printed Thread 5 Thread 6 : PrintQueue : Printing a Job during 5 seconds The document has been printed Thread 6 Thread 7 : PrintQueue : Printing a Job during 8 seconds The document has been printed Thread 7 Thread 8 : PrintQueue : Printing a Job during 9 seconds The document has been printed Thread 8 Thread 9 : PrintQueue : Printing a Job during 2 seconds The document has been printed Thread 9
五、tryLock()方法1、lock实现一个临界区,并保证同一时间只有一个执行线程访问这个临界区,必须创建一个ReentrantLock对象
2、在临界区的开始,必须通过lock()方法获取对锁的控制
3、当线程A访问这个方法时,如果没有其他线程获取对这个锁的控制,lock()方法将让这个线程A得到锁并且允许它立刻执行临界区代码
4、否则,lock方法将让线程A休眠直到线程B执行完临界区的代码
5、必须保证unlock()方法得到执行,否则导致死锁
这个方法是Lock()接口的方法。这个方法和lock方法的区别是tryLock()方法返回的是一个boolean值,当返回值是true是表示取得了锁,返回值是false时,立即返回,不会将线程置入休眠