苦逼菜狗程序猿,用来总结和备忘,大家勿喷。
线程安全
- 概念
多个线程并发访问一个类,一个类始终都能表现出正确的行为。 - 线程安全和非安全的代码列子
非全选代码举例package org.cc.safely; public class CountTest implements Runnable { private int count=5; @Override public void run() { count--; System.out.println("count="+count); // TODO Auto-generated method stub } public static void main(String[] args) { CountTest test=new CountTest(); Thread t1=new Thread (test); Thread t2=new Thread (test); Thread t3=new Thread (test); Thread t4=new Thread (test); Thread t5=new Thread (test); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); }
线程安全(synchronized关键字)public synchronized void run() { count--; System.out.println("count="+count); // TODO Auto-generated method stub }
ThreadLocal
- ThreadLocal概述
是一种并发访问线程的解决方案,为每个线程提供独立副本,以保障线程安全,是一种以空间换时间的手段。 - ThreadLocal和synchronized的区别
上面我们使用synchronized关键字保证线程的安全,synchronized关键字的作用就是利用同步机制保证每次只有一个线程可以操作synchronized修饰的方法或代码块,其他线程只能等待。多线程的情况下比较消耗时间。而ThreadLocal是为每个线程提供单独的区域去执保障时间。简单来讲,synchronized比较消耗时间ThreadLocal比较消耗空间。 - ThreadLocal的基本用法
package org.cc; public class UseThreadLocal { public static ThreadLocal<String> tl = new ThreadLocal<>(); public String getThreadLocal() { return tl.get(); } public void setThreadLocal(String threadLocal) { tl.set(threadLocal); } public static void main(String[] args) throws InterruptedException { UseThreadLocal utl=new UseThreadLocal(); Thread t1 = new Thread(()->{ utl.setThreadLocal("张三"); System.out.println("当前t1线程"+utl.getThreadLocal()); }); Thread t2 = new Thread(()->{ utl.setThreadLocal("李四"); System.out.println("当前t2线程"+utl.getThreadLocal()); }); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } t1.start(); t2.start(); t1.join(); t2.join(); //ThreadLocal会为每个线程提供独立副本,主线程没有设置值所以会返回null System.out.println("当前值: " + utl.getThreadLocal()); } }