23 ThreadLocal

来源:互联网 发布:npm node sass 淘宝 编辑:程序博客网 时间:2024/05/18 00:27

1、多线程访问临界资源时数据安全问题
   多个线程间共享的数据称为临界资源(Critical Resource),
   由于是线程调度器负责线程的调度,
   程序员无法精确控制多线程的交替顺序。
   因此,多线程对临界资源的访问有时会导致数据的不一致行。
  2、synchronized关键字

   a、 每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
          b、 Java对象默认是可以被多个线程共用的,只是在需要时才启动“互斥锁”机制,成为专用对象。
          c、关键字synchronized用来与对象的互斥锁联系
          d、当某个对象用synchronized修饰时,表明该对象已启动“互斥锁”机制,
   在任一时刻只能由一个线程访问,即使该线程出现堵塞,该对象的被锁定状态也不会解除,其他线程任不能访问该对象。
  3、死锁

   a、互斥条件:一个资源每次只能被一个进程使用。
   b、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
   c、不可剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
   d、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
 
   如何避免死锁:
   a、 等待某个资源时,使用超时机制。
   b、采用消息通信的通信机制,而不是共享内存的通信机制。
  4、ThreadLocal
   a、每个线程都有自己的局部变量
    每个线程都有一个独立于其他线程的上下文来保存这个变量,一个线程的本地变量对其他线程是不可见的(有前提,后面解释)
   b、独立于变量的初始化副本
    ThreadLocal可以给一个初始值,而每个线程都会获得这个初始化值的一个副本,这样才能保证不同的线程都有一份拷贝。
   c、状态与某一个线程相关联
    ThreadLocal 不是用于解决共享变量的问题的,不是为了协调线程同步而存在,而是为了方便每个线程处理自己的状态而引入的一个机制。


  代码示例:

import java.util.List;public class ChoiceRedBallRunable implements Runnable{private ThreadLocal<List<Integer>> threadLocal ;public ChoiceRedBallRunable(ThreadLocal<List<Integer>> threadLocal){this.threadLocal = threadLocal;}@Overridepublic void run() {synchronized(threadLocal){for (int i = 0; i < 6; i++) {System.out.print(randomBallIndex() + ",");}System.out.println("----" + Thread.currentThread().getName());}}public Integer randomBallIndex(){List<Integer> list = threadLocal.get();int index = (int) (Math.random() * threadLocal.get().size());Integer tempBall = list.remove(index);threadLocal.set(list);return tempBall;}}
public class ChoiceTest {private static ThreadLocal<List<Integer>> threadLocal = new ThreadLocal<List<Integer>>(){@Overrideprotected List<Integer> initialValue() {List<Integer> list = new ArrayList<>();for (int i = 1; i < 33; i++) {list.add(i);}return list;}};public static void main(String[] args) {ChoiceRedBallRunable choiceRedBallRunable = new ChoiceRedBallRunable(threadLocal);Thread thread1 = new Thread(choiceRedBallRunable, "A");Thread thread2 = new Thread(choiceRedBallRunable, "B");Thread thread3 = new Thread(choiceRedBallRunable, "C");Thread thread4 = new Thread(choiceRedBallRunable, "D");Thread thread5 = new Thread(choiceRedBallRunable, "E");thread1.start();thread2.start();thread3.start();thread4.start();thread5.start();}}



 

0 0
原创粉丝点击