线程高级篇-Synchronized锁,Lock锁区别和Condition线程并行
来源:互联网 发布:小米生态链产品 知乎 编辑:程序博客网 时间:2024/06/03 23:38
浅谈Synchronized:
synchronized是Java的一个关键字,也就是Java语言内置的特性,如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,执行代码块时,其他线程
便只能一直等待,等待获取锁的线程释放锁,而获取锁的线程释放锁会有三种情况:
1).获取锁的线程执行完该代码块,然后线程释放对锁的占有;
2).线程执行发生异常,此时JVM会让线程自动释放锁;
3).调用wait方法,在等待的时候立即释放锁,方便其他的线程使用锁.
Lock的特性:
1).Lock不是Java语言内置的;
2).synchronized是在JVM层面上实现的,如果代码执行出现异常,JVM会自动释放锁,但是Lock不行,要保证锁一定会被释放,就必须将unLock放到finally{}中(手动释放);
3).在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetarntLock,但是在很激烈的情况下,synchronized的性能会下降几十倍;
4).ReentrantLock增加了锁:
a. void lock(); // 无条件的锁;
b. void lockInterruptibly throws InterruptedException;//可中断的锁;
解释: 使用ReentrantLock如果获取了锁立即返回,如果没有获取锁,当前线程处于休眠状态,直到获得锁或者当前线程可以被别的线程中断去做其他的事情;但是如果是synchronized的话,如果没有获取到锁,则会一直等待下去;
c. boolean tryLock();//如果获取了锁立即返回true,如果别的线程正持有,立即返回false,不会等待;
d. boolean tryLock(long timeout,TimeUnit unit);//如果获取了锁立即返回true,如果别的线程正持有锁,会等待参数给的时间,在等待的过程中,如果获取锁,则返回true,如果等待超时,返回false;
5)Lock的ReentrantReadWriteLock读写锁 适用于 读多写少的场景 效率较高
Condition的特性:
1.Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。不同的是,Object中的这些方法是和同步锁捆绑使用的;而Condition是需要与互斥锁/共享锁捆绑使用的。
2.Condition它更强大的地方在于:能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition。
例如,假如多线程读/写同一个缓冲区:当向缓冲区中写入数据之后,唤醒”读线程”;当从缓冲区读出数据之后,唤醒”写线程”;并且当缓冲区满的时候,”写线程”需要等待;当缓冲区为空时,”读线程”需要等待。
如果采用Object类中的wait(), notify(), notifyAll()实现该缓冲区,当向缓冲区写入数据之后需要唤醒”读线程”时,不可能通过notify()或notifyAll()明确的指定唤醒”读线程”,而只能通过notifyAll唤醒所有线程(但是notifyAll无法区分唤醒的线程是读线程,还是写线程)。 但是,通过Condition,就能明确的指定唤醒读线程。
实例
ListAdd.java 使用synchronized
package ThreadCollections;import java.util.ArrayList;import java.util.List;/** * Created by 胖大星 on 2017/9/12. */public class ListAdd { private volatile static List list = new ArrayList(); public void addList(){ list.add("hello"); } public int size(){ return list.size(); } public static void main(String[] agrs){ final ListAdd list1 = new ListAdd(); Object lock = new Object(); Thread thread = new Thread(new Runnable(){ @Override public void run() { try { synchronized (lock){ for (int i = 0; i < 10; i++) { list1.addList(); System.out.println("当前线程为: "+Thread.currentThread().getName()+" "+i); Thread.sleep(500); if(list.size() == 5){ System.out.println("当前通知已发出!"); lock.notify(); } } } } catch (InterruptedException e){ e.printStackTrace(); } } },"t1"); Thread thread2 = new Thread(new Runnable() { @Override public void run() { synchronized (lock) { if (list1.size() != 5) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("当前线程:" + Thread.currentThread().getName()+"已经收到通知"); throw new RuntimeException(); } } },"t2"); thread2.start(); thread.start(); }}
UseReentrantLock.java 使用Lock
package Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by 胖大星 on 2017/9/17. * Lock 比 synchronized 方法更加便捷,灵活 */public class UseReentrantLock { //new ReentrantLock(false) 可以带参数 false 表示非公平锁(根据cpu分配优先执行) true表示公平锁(先来先执行) private ReentrantLock lock = new ReentrantLock(); public void method1(){ try { lock.lock(); System.out.println("当前线程:"+Thread.currentThread().getName()+"进入method1..."); Thread.sleep(1000); System.out.println("当前线程:"+Thread.currentThread().getName()+"退出method1..."); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public void method2(){ try { lock.lock(); System.out.println("当前线程:"+Thread.currentThread().getName()+"进入method2..."); Thread.sleep(1000); System.out.println("当前线程:"+Thread.currentThread().getName()+"退出method2..."); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public static void main(String[] args) { UseReentrantLock useReentrantLock = new UseReentrantLock(); Thread t1 = new Thread(new Runnable() { @Override public void run() { useReentrantLock.method1(); useReentrantLock.method2(); } }, "t1"); t1.start(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } }}
UseManyCondition.java 使用多个Condition
package Lock;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by 胖大星 on 2017/9/17. *启动多个 Condition 并行锁 同时并行多个线程 */public class UseManyCondition { private ReentrantLock lock = new ReentrantLock(); private Condition c1 = lock.newCondition(); private Condition c2 = lock.newCondition(); public void m1(){ try { lock.lock(); System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m1等待.."); c1.await(); System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m1继续.."); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void m2(){ try { lock.lock(); System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m2等待.."); c1.await(); System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m2继续.."); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void m3(){ try { lock.lock(); System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m3等待.."); c2.await(); System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m3继续.."); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void m4(){ try { lock.lock(); System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒.."); c1.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void m5(){ try { lock.lock(); System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒.."); c2.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public static void main(String[] args) { final UseManyCondition umc = new UseManyCondition(); Thread t1 = new Thread(new Runnable() { @Override public void run() { umc.m1(); } },"t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { umc.m2(); } },"t2"); Thread t3 = new Thread(new Runnable() { @Override public void run() { umc.m3(); } },"t3"); Thread t4 = new Thread(new Runnable() { @Override public void run() { umc.m4(); } },"t4"); Thread t5 = new Thread(new Runnable() { @Override public void run() { umc.m5(); } },"t5"); t1.start(); // c1 t2.start(); // c1 t3.start(); // c2 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } t4.start(); // c1 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } t5.start(); // c2 }}
UseReentrantReadWriteLock.java Lock使用读写锁
package Lock;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * Created by 胖大星 on 2017/9/17. * lock的ReentrantReadWriteLock读写锁 适用于 读多写少的场景 效率较高 */public class UseReentrantReadWriteLock { private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock(); private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock(); public void read(){ try { readLock.lock(); System.out.println("当前线程:"+Thread.currentThread().getName()+"进入...."); Thread.sleep(3000); System.out.println("当前线程:"+Thread.currentThread().getName()+"退出...."); } catch (InterruptedException e) { e.printStackTrace(); }finally { readLock.unlock(); } } public void write(){ try { writeLock.lock(); System.out.println("当前线程:"+Thread.currentThread().getName()+"进入...."); Thread.sleep(3000); System.out.println("当前线程:"+Thread.currentThread().getName()+"退出...."); } catch (InterruptedException e) { e.printStackTrace(); }finally { writeLock.unlock(); } } public static void main(String[] args) { UseReentrantReadWriteLock useReentrantReadWriteLock = new UseReentrantReadWriteLock(); Thread threadRead1 = new Thread(new Runnable() { @Override public void run() { useReentrantReadWriteLock.read(); } }, "threadRead1"); Thread threadRead2 = new Thread(new Runnable() { @Override public void run() { useReentrantReadWriteLock.read(); } }, "threadRead2"); Thread threadWrite1 = new Thread(new Runnable() { @Override public void run() { useReentrantReadWriteLock.write(); } }, "threafWrite1"); Thread threadWrite2 = new Thread(new Runnable() { @Override public void run() { useReentrantReadWriteLock.write(); } }, "threafWrite2"); //两个读线程同时开始 ,写线程明显较慢 threadRead1.start(); // threadRead2.start(); threadWrite1.start(); // threadWrite2.start(); }}
- 线程高级篇-Synchronized锁,Lock锁区别和Condition线程并行
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- Java线程---锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- 【Java线程】锁机制:synchronized、Lock、Condition
- more effective 一些设计模式解析一
- js常用方法(写给自己)
- 数学建模
- 左右最值最大差
- Ambaria整体架构
- 线程高级篇-Synchronized锁,Lock锁区别和Condition线程并行
- 1111 Dijkstra+DFS
- OSI七层模型和TCP/IP五层模型
- hadoop之大数据初识
- 软件设计考试剖析
- jq实现鼠标拖拽效果
- Windows Practice_文件_文件分割器(二)
- [LeetCode] 58.Length of Last Word
- Pythonic Data Structures and Algorithms(Array 2)