多线程是Java实现多任务的基础:java
Thread对象表明一个线程:调用Tread.currentThread()获取当前线程。
多任务程序一般须要针对每一个任务启动一个新的线程,来处理这个用户的请求,也能够从线程池取出一个空闲的线程来处理。
如何在一个线程内传递状态:
例如咱们在一个线程处理过程当中,常常须要调用不一样的类来处理不一样的功能,咱们如何在这些方法中可以方便的获取到当前的用户?
JDK提供了ThreadLocal在一个线程中传递同一个对象多线程
static ThreadLocal<String> threadLocalUser = new ThreadLocal<>(); threadLocalUser.set("Bob"); //给当前线程绑定一个指定的值 ... String current = threadLocalUser.get(); //调用get()方法能够在当前线程随时获取到已绑定的这个值 String current = threadLocalUser.get(); String current = threadLocalUser.get(); ... threadLocalUser.remove(); //把绑定的值从当前线程中解除
ThreadLocal典型的使用方式:
ThreadLocal必定要在finally中清除。当前线程执行完相关代码之后,颇有可能从新放入线程池中,若是ThreadLocal没有被清除,这个线程在执行其余代码的时候,就会把上一次的状态带进去。this
try{ UserContext.set(user); ... }finally{ UserContext.remove(); }
class User{ //表示当前的一个用户 String name; int level; public User(String name, int level){ this.name = name; this.level = level; } } class UserContext implements AutoCloseable{ static final ThreadLocal<User> context = new ThreadLocal<>(); //全局惟一静态变量 public static User getCurrentUser(){ //获取当前线程的ThreadLocal User return context.get(); } public UserContext(User user){ //初始化ThreadLocal的User context.set(user); } public void close(){ //移除ThreadLocal关联的User context.remove(); } } class ProcessThread extends Thread{ User user; ProcessThread(User user){ //传入User对象 this.user = user; } public void run(){ try(UserContext ctx = new UserContext(user)){ new Greeting().hello(); Level.checkLevel(); } } } class Greeting{ void hello(){ User user = UserContext.getCurrentUser(); System.out.println("Hello,"+user.name+"!"); } } class Level{ static void checkLevel(){ User user = UserContext.getCurrentUser(); if(user.level>100){ System.out.println(user.name+" is a VIP user."); }else{ System.out.println(user.name+" is a registered user."); } } } public class Main{ public static void main(String[] args) throws Exception{ Thread t1 = new ProcessThread(new User("Bob",120)); Thread t2 = new ProcessThread(new User("Alice",80)); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("Main end"); } }
能够把ThreadLocal当作全局Map<Thread, Object>:线程
Object ThreadLocalValue = threadLocalMap.get(Thread.currentThread());