Java多线程知识点整理(Lock锁)

1.Lock的使用java

private Lock lock = new ReentrantLock();

public void test(){
   lock.lock();

   System.out.println("#######");
     
   lock.unlock();

}

注意:try-catch-finally结合使用,unlock()在finally里面。ide

2.使用condition实现等待/通知spa

    关键字synchronized与wait()和notify()/notifyAll()方法相结合能够实现等待/通知模式,类ReentrantLock也能够实现一样的功能,但须要借助Condition对象。能够实现多路通知功能,也就是在一个Lock对象里面能够建立多个Condition实例,线程对象能够注册在指定Condition中,从而能够有选择性进行线程通知,在调度线程上更加灵活。线程

    synchronized的wait()和notify(),而Condition对象,却能够选择性通知。code

2.1 使用condition API对象

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

public class test5 {
	
	private Lock lock = new  ReentrantLock();
	
	public Condition condition1 = lock.newCondition();
	
	public Condition condition2 = lock.newCondition();
	
	public void awaitA(){
		try {
			lock.lock();
			System.out.println("A等待");
			condition1.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
		
	}
	public void awaitB(){
		try {
			lock.lock();
			System.out.println("B等待");
			condition2.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	public void signalA(){
		try {
			lock.lock();
			System.out.println("通知a");
			condition1.signalAll();
		} finally {
			lock.unlock();
		}
			// TODO: handle finally clause
		}
	public void signalB(){
		try {
			lock.lock();
			System.out.println("通知B");
			condition2.signalAll();
		} finally {
			lock.unlock();
		}
			// TODO: handle finally clause
		}
	
	public static void main(String[] args) {
		
		test5 t5 = new test5();
		//建立两个线程
		// Thread thread1= new Thread(t5);
		//Thread thread2= new Thread(t5);
		//只通知线程1
		//
		t5.signalA();
	}
}

2.二、生产者与消费模式:交替打印get

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

public class test6 {
	private Lock lock =new ReentrantLock();
	
	private Condition condition=  lock.newCondition();
	
	private boolean hasValue= false;
	public void set(){
		try {
		lock.lock();
		while(hasValue == true){
			condition.await();
		}
		System.out.println("@@@");
		hasValue= true;
		condition.signal();
		
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			lock.unlock();
		}
	}
	
	public void get(){
		try {
			lock.lock();
			while(hasValue == false){
				condition.await();
			}
			System.out.println("###");
			hasValue= false;
			condition.signal();
			
			} catch (Exception e) {
				// TODO: handle exception
			}finally {
				lock.unlock();
			}
	}
	public static void main(String[] args) {
		test6 test6 = new test6();
		//建立两个线程
		//启动
	}
}

注意:多消费者和多生产者,使用condition.signalAll();it

3.公平锁与非公平锁io

    锁Lock分为“公平锁”和“非公平锁”,公平锁表示线程获取的顺序是按照线程加锁的顺序来分配的,即先来得的FIFO先进先出的顺序。而非公平锁就是一种获取抢占机制,是随机得到锁的,和公平锁不同就是先来得不必定先获得锁,这个方式可能形成某些线程一直拿不到锁,结果也就是不公平的了。class

import java.util.concurrent.locks.ReentrantLock;

public class test7 {
	private ReentrantLock lock;
	public test7(boolean isFair){//传入true表示公平锁,反之为非公平锁
		super();
		lock = new ReentrantLock();
	}
	public void add(){
		try {
			lock.lock();
			
		} finally {
			lock.unlock();
		}
		
	}
}

4.API讲解

4.一、方法lockInterruptibly()

    该方法的做用是:若是当前线程未被中断,则获取锁定,若是已经被中断则抛出异常。

4.二、tryLock()

    改方法的做用是:仅在调用时锁定未被另外一个线程保持的状况下,才获取该锁。

private Lock lock = new ReentrantLock();

public void test(){
   if(lock.tryLock()){
      System.out.println("#######");

   }

}

    同时,tryLock(long timeout,TimeUnit unit)的做用是,若是锁定在给等待时间内没有被另外一个线程保持,且当前线程未被中断,则获取该锁定。

4.三、使用Condition实现顺序执行

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

public class test8 {
	volatile private static int nextPrintWho =1;
	private static ReentrantLock lock = new ReentrantLock();
	final private static Condition conditionA = lock.newCondition();
	final private static Condition conditionB = lock.newCondition();
	final private static Condition conditionC = lock.newCondition();
	public static void main(String[] args) {
		Thread threadA = new Thread(){
			@Override
			public void run() {
				try {
					lock.lock();
					while(nextPrintWho != 1){
						conditionA.await();
					}
					for(int i=1; i<4;i++){
						System.out.println("ThreadA"+i);
					}
					nextPrintWho = 2;
					conditionB.signalAll();
				} catch (Exception e) {
					// TODO: handle exception
				}finally {
					lock.unlock();
				}
			}
		};
		Thread threadB = new Thread(){
			@Override
			public void run() {
				try {
					lock.lock();
					while(nextPrintWho != 2){
						conditionB.await();
					}
					for(int i=1; i<4;i++){
						System.out.println("ThreadB"+i);
					}
					nextPrintWho = 3;
					conditionC.signalAll();
				} catch (Exception e) {
					// TODO: handle exception
				}finally {
					lock.unlock();
				}
			}
		};
		Thread threadC = new Thread(){
			@Override
			public void run() {
				try {
					lock.lock();
					while(nextPrintWho != 3){
						conditionC.await();
					}
					for(int i=1; i<4;i++){
						System.out.println("ThreadC"+i);
					}
					nextPrintWho = 1;
					conditionA.signalAll();
				} catch (Exception e) {
					// TODO: handle exception
				}finally {
					lock.unlock();
				}
			}
		};
		Thread[] aAray =new Thread[5];
		Thread[] bAray =new Thread[5];
		Thread[] cAray =new Thread[5];
		for(int i=0;i<5;i++){
			aAray[i] =new Thread(threadA);
			 bAray[i] =new Thread(threadB);
			 cAray[i] =new Thread(threadC);
			 aAray[i].start();
			 bAray[i].start();
					 cAray[i].start();
		}
		
	}
}

总结:实现线程的顺序执行,可使用:join方法,也可使用Condition。

5.使用ReentrantReadWriteLock类

    读写锁表示有两个锁,一个是读操做相关的锁,也称为共享锁;另外一个是写操做相关的的锁,也叫排它锁。也就是多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。在没有线程进行写入操做时,进行读取操做的多个线程均可以获取锁,而进行写入的操做的线程只有在获取写锁后才能进行操做。即多个线程能够同时进行读取操做,可是同一时刻只容许一个线程进行写入操做。

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class test9 {
	
	private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	public void read(){
		try {
			lock.readLock();
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			lock.readLock().unlock();
		}
	}
	
	public void wirte(){
		try {
			lock.writeLock();
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			lock.writeLock().unlock();
		}
	}
}
相关文章
相关标签/搜索