多线程(七):ThreadLocal

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vbirdbest/article/details/81570618

多个线程共享同一个对象,所有线程都操作同一个对象。

public class ThreadLocalTest {
    public static void main(String[] args) {
        // 三个线程每个线程打印3次,所以从0打印到9
        IdWorker idWorker = new IdWorker();
        new Thread(new MyRunnable(idWorker, "A")).start();
        new Thread(new MyRunnable(idWorker, "B")).start();
        new Thread(new MyRunnable(idWorker, "C")).start();
    }
}

class IdWorker {
    private Long id = 0L;

    public String  generateId(String prefix) {
        return prefix + (++id);
    }
}

class MyRunnable implements Runnable {
    private IdWorker idWorker;
    private String prefix;
    public MyRunnable(IdWorker idWorker, String prefix) {
        this.idWorker = idWorker;
        this.prefix = prefix;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(new Date() + "\t" + Thread.currentThread().getName() + "\t" + idWorker.generateId(prefix));
        }
    }
}

这里写图片描述


三个线程分别操作各自的对象,每个对象分别打印自己的

public class ThreadLocalTest {
    public static void main(String[] args) {
        // 每个线程分别使用各自的IdWorker,所以每个线程分别打印自己的0、1、2
        // 要想达到每个线程分别使用自己的IdWorker,如果N个线程就必须创建N个对象
        IdWorker idWorkerA = new IdWorker();
        IdWorker idWorkerB = new IdWorker();
        IdWorker idWorkerC = new IdWorker();
        new Thread(new MyRunnable(idWorkerA, "A")).start();
        new Thread(new MyRunnable(idWorkerB, "B")).start();
        new Thread(new MyRunnable(idWorkerC, "C")).start();
    }
}

这里写图片描述


ThreadLocal(本地线程)将一个变量提供给所有线程,所有线程各自复制一份到自己的线程,每个线程持有的对象互不影响。

public class ThreadLocal<T> {
    ThreadLocal.ThreadLocalMap threadLocals = null;

    public ThreadLocal();

    protected T initialValue();

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
   }

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null) {
                m.remove(this);
         }

   }
   ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
   }

   void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
   }
}
public class ThreadLocalTest {
    public static void main(String[] args) {
        // 只创建一个对象,但是所有线程分别复制该对象,每个线程分别持有各自的对象
        // 与上一个示例相比,效果相同,但是上个示例创建了N个对象,此示例只创建了一个对象
        IdWorker idWorker = new IdWorker();
        new Thread(new MyRunnable(idWorker, "A")).start();
        new Thread(new MyRunnable(idWorker, "B")).start();
        new Thread(new MyRunnable(idWorker, "C")).start();
    }
}

class IdWorker {
    public static ThreadLocal<Long> threadLocal = new ThreadLocal<Long>() {
        @Override
        protected Long initialValue() {
            return 0L;
        }
    };

    public String generateId(String prefix) {
        long currentId = threadLocal.get() + 1;
        threadLocal.set(currentId);
        return prefix + currentId;
    }
}

class MyRunnable implements Runnable {
    private IdWorker idWorker;
    private String prefix;
    public MyRunnable(IdWorker idWorker, String prefix) {
        this.idWorker = idWorker;
        this.prefix = prefix;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(new Date() + "\t" + Thread.currentThread().getName() + "\t" + idWorker.generateId(prefix));
        }
    }
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/vbirdbest/article/details/81570618