thespringofmulti-thread——线程安全的另一种解决思路剖析

上传人:今*** 文档编号:107226004 上传时间:2019-10-18 格式:PPT 页数:27 大小:272.50KB
返回 下载 相关 举报
thespringofmulti-thread——线程安全的另一种解决思路剖析_第1页
第1页 / 共27页
thespringofmulti-thread——线程安全的另一种解决思路剖析_第2页
第2页 / 共27页
thespringofmulti-thread——线程安全的另一种解决思路剖析_第3页
第3页 / 共27页
thespringofmulti-thread——线程安全的另一种解决思路剖析_第4页
第4页 / 共27页
thespringofmulti-thread——线程安全的另一种解决思路剖析_第5页
第5页 / 共27页
点击查看更多>>
资源描述

《thespringofmulti-thread——线程安全的另一种解决思路剖析》由会员分享,可在线阅读,更多相关《thespringofmulti-thread——线程安全的另一种解决思路剖析(27页珍藏版)》请在金锄头文库上搜索。

1、,The spring of multi-thread 线程安全的另一种解决思路,我需要一个可靠的单例模式!,上堂回顾,public class InnDao private volatile static InnDao instance; private InnDao() public static InnDao getInstance() if (instance = null) synchronized (InnDao.class) / 1 if (instance = null) / 2 instance = new InnDao(); / 3 return instance; pub

2、lic final Model.Finder finder = new Model.Finder(Integer.class, Inn.class); ,关于Volatile与同步操作共同使用的思考,public class ThreadClient extends Thread private static int count; public void run() for(int i=0;i3;i+) System.out.println(“当前线程名:“+Thread.currentThread().getName() + “ count=“+count); count+; public

3、static void main(String args) ThreadClient tc1 = new ThreadClient(); ThreadClient tc2 = new ThreadClient(); ThreadClient tc3 = new ThreadClient(); tc1.start(); tc2.start(); tc3.start(); ,当前线程名:Thread-1 count=0 当前线程名:Thread-1 count=1 当前线程名:Thread-1 count=2 当前线程名:Thread-2 count=3 当前线程名:Thread-2 count=

4、4 当前线程名:Thread-2 count=5 当前线程名:Thread-0 count=6 当前线程名:Thread-0 count=7 当前线程名:Thread-0 count=8,public class ThreadClient extends Thread private static ThreadLocal count = new ThreadLocal(); public ThreadClient(Integer value) count.set(value); public void run() for(int i=0;i3;i+) System.out.println(“当

5、前线程名:“+Thread.currentThread().getName() + “ count=“+count.get(); count.set(count.get()+1); try TimeUnit.SECONDS.sleep(1); catch (InterruptedException e) e.printStackTrace(); public static void main(String args) ThreadClient tc1 = new ThreadClient(0); ThreadClient tc2 = new ThreadClient(0); ThreadCli

6、ent tc3 = new ThreadClient(0); tc1.start(); tc2.start(); tc3.start(); ,Exception in thread “Thread-1“ java.lang.NullPointerException at com.fanqie.oms.thread.ThreadLocal.ThreadClient.run(ThreadClient.java:21) Exception in thread “Thread-0“ java.lang.NullPointerException at com.fanqie.oms.thread.Thre

7、adLocal.ThreadClient.run(ThreadClient.java:21) 当前线程名:Thread-1 count=null 当前线程名:Thread-0 count=null Exception in thread “Thread-2“ java.lang.NullPointerException at com.fanqie.oms.thread.ThreadLocal.ThreadClient.run(ThreadClient.java:21) 当前线程名:Thread-2 count=null,public class ThreadClient extends Thr

8、ead private static ThreadLocal count = new ThreadLocal() Override protected Integer initialValue() return 0; ; public void run() for(int i=0;i3;i+) System.out.println(“当前线程名:“+Thread.currentThread().getName() + “ count=“+count.get(); count.set(count.get()+1); try TimeUnit.SECONDS.sleep(1); catch (In

9、terruptedException e) e.printStackTrace(); public static void main(String args) ThreadClient tc1 = new ThreadClient(); ThreadClient tc2 = new ThreadClient(); ThreadClient tc3 = new ThreadClient(); tc1.start(); tc2.start(); tc3.start(); ,当前线程名:Thread-0 count=0 当前线程名:Thread-1 count=0 当前线程名:Thread-2 co

10、unt=0 当前线程名:Thread-0 count=1 当前线程名:Thread-2 count=1 当前线程名:Thread-1 count=1 当前线程名:Thread-0 count=2 当前线程名:Thread-2 count=2 当前线程名:Thread-1 count=2,TimeUnit,public void test(String args) throws InterruptedException System.out.println(“Sleeping for 4 minutes using Thread.sleep()“); Thread.sleep(4 * 60 *

11、1000); System.out.println(“Sleeping for 4 minutes using TimeUnit sleep()“); TimeUnit.SECONDS.sleep(4); TimeUnit.MINUTES.sleep(4); TimeUnit.HOURS.sleep(1); TimeUnit.DAYS.sleep(1); ,ThreadLocal是什么,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 对外提供的方法很简单 publ

12、ic T get() ; public void set(T value); public void remove();有利于jvm回收 protected T initialValue(); 返回null,ThreadLocal并不能替代同步机制,两者面向的问题领域不同。同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信的有效方式;而ThreadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源(变量),这样当然不需要对多个线程进行同步了。所以,如果你需要进行多个线程之间进行通信,则使用同步机制;如果需要隔离多个线程之间的共享冲突,可以使用Thre

13、adLocal,这将极大地简化你的程序,使程序更加易读、简洁。,同步用时间换取空间, ThreadLocal用空间换取时间。,自己实现一个ThreadLocal,public class MyThreadLocal private Map map = Collections.synchronizedMap(new HashMap(); public T get() Thread thread = Thread.currentThread(); T value = map.get(thread); if(value = null ,public void set(T value) map.put

14、(Thread.currentThread(),value); public void remove() map.remove(Thread.currentThread(); protected T initialValue() return null; ,问题:性能低,内存无法释放 1.MyThreadLocal中的map大小会随着线程的增加而增加,当并发存在时,效率会很低。 2.当前线程结束后,实例依然存在,不会被GC回收,因为其他线程有可能依然还会在使用。,源码实现,源码实现,public T get() Thread t = Thread.currentThread(); Thread

15、LocalMap map = getMap(t); if (map != null) ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) return (T)e.value; return setInitialValue(); ,注意这里获取键值对传进去的是 this,而不是当前线程t。,源码实现,public void set(T value) Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set

16、(this, value); else createMap(t, value); ,源码实现,public void remove() ThreadLocalMap m = getMap(Thread.currentThread(); if (m != null) m.remove(this); ,static class ThreadLocalMap,public class ThreadLocal static class ThreadLocalMap static class Entry extends WeakReference Object value; Entry(ThreadLocal k, Object v) super(k);

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号