多线程与并发-----Lock锁技术

Lock

    java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,

    

接口摘要

Condition

Condition Object 监视器方法(waitnotify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 setwait-set)。

Lock

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。

ReadWriteLock

ReadWriteLock 维护了一对相关的,一个用于只读操作,另一个用于写入操作。

类摘要

AbstractOwnableSynchronizer

可以由线程以独占方式拥有的同步器。

AbstractQueuedLongSynchronizer

long 形式维护同步状态的一个 AbstractQueuedSynchronizer 版本。

AbstractQueuedSynchronizer

为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量、事件,等等)提供一个框架。

LockSupport

用来创建锁和其他同步类的基本线程阻塞原语。

ReentrantLock

一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

ReentrantReadWriteLock

支持与 ReentrantLock 类似语义的 ReadWriteLock 实现。

ReentrantReadWriteLock.ReadLock

ReentrantReadWriteLock.readLock() 方法返回的锁。

ReentrantReadWriteLock.WriteLock

ReentrantReadWriteLock.writeLock() 方法返回的锁。

Lock比传统线程模型中的synchronized更加面向对象,锁本身也是一个对象,两个线程执行的代码要实现同步互斥效果,就要使用同一个锁对象。锁要上在要操作的资源类的内部方法中,而不是线程代码中。

public interface Lock

所有已知实现类:

ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock 

随着灵活性的增加,也带来了更多的责任。不使用块结构锁就失去了使用 synchronized 方法和语句时会出现的锁自动释放功能。在大多数情况下,应该使用以下语句:

 Lock l = ...;

     l.lock();

     try {

         // access the resource protected by this lock

     } finally {

         l.unlock();

     }

锁定和取消锁定出现在不同作用范围中时,必须谨慎地确保保持锁定时所执行的所有代码用 try-finally try-catch 加以保护,以确保在必要时释放锁。

方法摘要

 void

lock()           获取锁。

 void

lockInterruptibly()           如果当前线程未被中断,则获取锁。

 Condition

newCondition()           返回绑定到此 Lock 实例的新 Condition 实例。

 boolean

tryLock()           仅在调用时锁为空闲状态才获取该锁。

 boolean

tryLock(long time, TimeUnit unit)           如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。

 void

unlock()           释放锁。

Locksynchronized对比,打印字符串例子


具体代码如下:


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadLock {

	public static void main(String[] args) {
		
		new ThreadLock().init();
	}
	
	public void init(){
		/*在静态方法中不能new内部类的实例对象,
		因为内部类的最重要的一个特点就是它可以直接访问它外部类的成员变量。成员变量是对象身上的。对象创建完成了,才会为成员变量分配空间。能调用成员变量,意味着一定有了实例对象.
		main方法是静态的,它执行的时候可以不用创建那个对象。这就矛盾了。 
		 */
		final Outputer outputer=new Outputer();//创建内部类
		new Thread(new Runnable() {//创建一个线程
			public void run() {
				while(true){
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					outputer.output("lisi");
				}
				
			}
		}).start();
		
		new Thread(new Runnable() {//创建一个线程
			public void run() {
				while(true){
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					outputer.output("zhangsan");
				}
				
			}
		}).start();
	}
		
	//内部类
	class Outputer{
		Lock lock =new ReentrantLock();
		public void output(String name){
			int len=name.length();
			lock.lock();
			try{
				for(int i=0;i<len;i++){
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}finally{
				lock.unlock();
			}			
		}
	}
}

猜你喜欢

转载自blog.csdn.net/pengzhisen123/article/details/80292992