多线程并发的解决方案 volatile synchronized notify notifyAll wait关键字分析
2016-03-09 00:00
309 查看
摘要: 多线程并发的解决方案 volatile notify notifyAll wait关键字分析
ThreadLocal使得各线程能够保持各自独立的一个对象,通过ThreadLocal.set()来设置对象的值,保存在每个线程自己都有的一个map对象当中,每个ThreadLocal对象会有一个线程范围内唯一hashcode作为key,ThreadLocal.get()内部通过这个key从map中取值,因此取出来的是各自自己线程中的对象,ThreadLocal实例事实上只是作为map的key来使用的
ThreadLocal例子
2. Lock可以实现公平锁或不公平锁,而Synchronized是不公平的,而且永远都是不公平的。但 JVM 保证了所有线程最终都会得到它们所等候的锁,但是Lock作为默认设置,把公平设置为false
3. Lock性能和伸缩性都比较好(在JDK5.0),但是大多数情况Synchronized就足够了,而且更容易理解
4.ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”。也就是说ReentrantLock在同一个时间点只能被一个线程获取
4. 重要点
1).当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块
2).当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块
1.ThreadLocal用法
在java中,如果一个变量需要被多个线程访问,可以使用volatile来声明它为“易变的”。而假如一个变量要被持有它的某个线程独享,在java中,它可以使用java.lang.ThreadLocal类来实现线程本地存储的功能。这样,数据便只在同一个线程内可见和共享,因此,即便不同步也能保证线程之间不出现数据争用。ThreadLocal使得各线程能够保持各自独立的一个对象,通过ThreadLocal.set()来设置对象的值,保存在每个线程自己都有的一个map对象当中,每个ThreadLocal对象会有一个线程范围内唯一hashcode作为key,ThreadLocal.get()内部通过这个key从map中取值,因此取出来的是各自自己线程中的对象,ThreadLocal实例事实上只是作为map的key来使用的
ThreadLocal例子
package com.arch.demo; public class ThreadLocalTest { public static void main(String[] args) { ThreadLocal<Integer> count = new ThreadLocal<>(); ConcurrentThread t1 = new ConcurrentThread(count); ConcurrentThread t2 = new ConcurrentThread(count); ConcurrentThread t3 = new ConcurrentThread(count); ConcurrentThread t4 = new ConcurrentThread(count); t1.start(); t2.start(); t3.start(); t4.start(); } static class ConcurrentThread extends Thread { ThreadLocal<Integer> threadLocal = new ThreadLocal<>(); private ConcurrentThread(ThreadLocal<Integer> count) { this.threadLocal = count; } @Override public void run() { for (int i = 1; i < 10; i++) { if (threadLocal.get() != null) { threadLocal.set(threadLocal.get() + 1); } else { threadLocal.set(1); } System.out.println("Thread:" + this.currentThread().getName() + ",Count:" + threadLocal.get()); } } } }
2.volatile用法
volatile是轻量级的synchronized, 它在多处理器开发中保证了共享变量的"可见性", 可见性是指一个线程在修改共享变量的值时,其他的线程可以读到这个修改的值3.Synchronized与ReentranckLock区别
Lock和 synchronized 有一点明显的区别 —— lock 必须在 finally 块中释放2. Lock可以实现公平锁或不公平锁,而Synchronized是不公平的,而且永远都是不公平的。但 JVM 保证了所有线程最终都会得到它们所等候的锁,但是Lock作为默认设置,把公平设置为false
3. Lock性能和伸缩性都比较好(在JDK5.0),但是大多数情况Synchronized就足够了,而且更容易理解
4.ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”。也就是说ReentrantLock在同一个时间点只能被一个线程获取
4. 重要点
1).当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块
public class SynchronizedThread implements Runnable { @Override public void run() { synchronized (this){ for(int i = 0; i < 5; i++){ System.out.println(Thread.currentThread().getName() + " synchronized loop" + i); } } } public static void main(String[] args) { Runnable runnable = new SynchronizedThread(); new Thread(runnable,"a").start(); new Thread(runnable,"b").start(); } }
2).当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块
相关文章推荐
- 关闭窗体后,进程仍然在运行的问题重现与解决
- C#多线程开发3:给线程传递数据的两种方法
- C#多线程开发4:线程的Abort和ResetAbort方法
- C#多线程开发5:线程的Abort和Interrupt方法
- Windows多线程开发之并发线程程序研究
- iOS开发系列--并行开发其实很容易
- CountDownLatch的使用
- AIR程序生成系统托盘
- Adobe AIR迷你教程 -- 使用自定义窗口以及对窗口的移动,缩放,关闭操作
- AIR2.0特性回顾
- AIR文件操作:使用文件对象操作文件和目录
- AIR数据处理的方法
- [转]AIR中调用exe或者bat可执行文件
- AIR 教程:生成100%透明窗口,以及打包成.air
- canvas,paint的用法
- sleep和wait的区别
- Codeforces 651B Beautiful Paintings(贪心策略—两个优先队列实现)
- Apache启动提示 httpd: apr_sockaddr_info_get() failed for xxx
- Longtail Hedgehog(DP)
- Contains Duplicate II-副本包含