TreadLocal对象的作用和实现原理

TreadLocal对象的作用和实现原理

作用:

ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定的线程中可以获取到存储的数据,对于其他线程来说则无法取到数据。

实现原理:

ThreadLocal是一个泛型类,定义为public class ThreadLocal,只要弄清楚ThreadLocal的get方法和set方法,就可以明白它的实现原理。

set方法底层实现:

先获取线程对象,用线程对象的引用来获取当前线程的ThreadLocalMap,如果不是空则map.set(this,value);如果是空那么创建map,再设值map.set(t,value);

get方法底层实现:

先获取线程对象,用getMap方法来获取当前线程的ThreadLocalMap,然后根据key=当前ThreadLocal来获取对应的value值。

不管是get还是set都是要用到ThreadLocalMap来操作的,对ThreadLocalde的读、写操作仅限于各自线程的内部,从而使ThreadLocal可以在多个线程中互不干扰地存储和修改数据。

主要方法:

set(T value)方法用于设置副本变量的值
get()方法用于获取当前线程副本变量的值
initialValue()为当前线程默认的副本变量值。
remove()方法移除当前前程的副本变量值。

最常见的ThreadLocal使用场景为 用来解决 数据库连接、Session管理。

线程创建的三种方法:

1.继承Thread类,重写run方法:
class MyThread extends Thread{
public void run(){
for(int i=0;i<100;i++){
System.out.println("+++++++"+i);
}
}
}
Thread t = new MyThread();
t.start();

2.实现Runnable接口
class MyTarget implements Runnable{
public void run(){
for(int i = 0 ;i<100;i++){
System.out.println("+++++++"+i);
}
}
}
MyTarget target = new MyTarget();
Thread t = new Thread(target);
t.start();

  1. 使用Callable和Future创建。

线程的状态:

new:至今尚未启动的线程处于这种状态。
runnable:正在java虚拟机中执行的线程处于这种状态。
blocked:阻塞状态。
waiting:等待另外一个线程执行完毕。在执行此线程。
1.join():允许其他线程加入当前线程,并且当其它线程执行完毕后才会继续执行当前线程。
timed_waiting:线程休眠状态。
2.sleep(long 毫秒):进入休眠状态。
terminated:已退出的线程处于这种状态。

多线程的作用

1.提高硬件的利用率。
2.提高用户的体验度。
3.模拟现实世界。

线程同步

线程不安全

当多线程并发访问临界资源时,如果破坏原子操作,可能会导致数据不一致,

临界资源:

共享资源(同一对象),一次仅允许一个线程使用,才可保证其正确性。

原子操作:

不可分割的多步操作,被视为一个整体,其顺序和步骤不可打乱或缺省。

synchronized(锁标记)

在方法上或者不可分割和缺省的代码块上加上锁标记来确保线程的原子性(安全性);

死锁

当第一个线程拥有A对象的锁标记,并等待B对象锁标记,同时第二个线程拥有B对象的锁标记,并等待A对象锁标记时,产生死锁。

线程安全的并发集合

Collection 
	List
		ArrayList 线程不安全:
		LinkedList
		Vector   线程安全
		CopyOnWriteArrayList  cow(写时复制)  读写分离

				
   Set
		HashSet
		LinkedHashSet
		CopyOnWriteArraySet
	    SortedSet:
		TreeSet
		
		Queue  
		BlockingQueue 阻塞队列集合 先入先出(FIFO)  生产者消费者
		 void put(E e) :将指定元素插入此队列中,若没有可用的空间,将阻塞。
			E take() :获取并移除此队列的头部元素,若其中没有可用的有效元素,将阻塞。
			
			实现类:
				ArrayBlockingQueue: 数组实现  有界队列
				LinkedBlockingQueue: 链表实现  无界队列

    Map
	    HashMap
	    LinkedHashMap
	    HashTable  线程安全
	    TreeMap
	    ConcurrentHashMap  JDK 1.5 分段锁  默认有16段 
					   JDK 1.7  CAS算法 

线程池

①ExecutorService:线程池接口
常用方法:
	submit(Runnable task):提交任务给线程池,线程池会自动为你分配对应的线程 执行任务。
	void shutdown()  :关闭线程池。
	
②Executors:工具类
	static ExecutorService newFixedThreadPool(int nThreads):返回一个创建固定线程的线程池对象
	static ExcutoursService newCachedThreadPool():返回一个线程池对象,新建的线程池没有线程,当提交任务时,新建一个线程 
③获取线程池对象的方式
	//创建一个线程池对象  线程池中有两个线程对象
	ExecutorService  es = Executors.newFixedThreadPool(2);
	//向线程池提交任务
	es.submit(r1);
	es.submit(r2);
	es.submit(r3);
	es.submit(r4);
	//关闭线程池,等待任务完成后
	es.shutdown(); 

Callable:返回结果并且可能抛出异常的线程任务。
Future:返回异步计算的结果。	

你可能感兴趣的:(面试题)