Java并发编程-08-使用锁实现同步

一、使用锁实现同步

基于Lock接口及其实现类,Lock接口及其实现类如下:



二、和synchronized相比

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();
		}
	}
}

输出:


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

四、Lock原理

1、lock实现一个临界区,并保证同一时间只有一个执行线程访问这个临界区,必须创建一个ReentrantLock对象

2、在临界区的开始,必须通过lock()方法获取对锁的控制

3、当线程A访问这个方法时,如果没有其他线程获取对这个锁的控制,lock()方法将让这个线程A得到锁并且允许它立刻执行临界区代码

4、否则,lock方法将让线程A休眠直到线程B执行完临界区的代码

5、必须保证unlock()方法得到执行,否则导致死锁


五、tryLock()方法

这个方法是Lock()接口的方法。这个方法和lock方法的区别是tryLock()方法返回的是一个boolean值,当返回值是true是表示取得了锁,返回值是false时,立即返回,不会将线程置入休眠

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值