ThreadLocal.withInitial

ThreadLocal的Lambda构造方式

Java8中ThreadLocal对象提供了一个Lambda构造方式,实现了非常简洁的构造方法:withInitial

这个方法采用Lambda方式传入实现了 Supplier 函数接口的参数。

银行存款实例

@SuppressWarnings("all")
public class Test {
    
    public static void main(String[] args) {
        safeDeposit();
        notSafeDeposit();
    }

    /**
     * 线程安全的存款
     */
    private static void safeDeposit() {
        SafeBank bank = new SafeBank();
        Thread thread1 = new Thread(() -> bank.deposit(200), "jak");
        Thread thread2 = new Thread(() -> bank.deposit(200), "马云");
        Thread thread3 = new Thread(() -> bank.deposit(500), "马化腾");
        thread1.start();
        thread2.start();
        thread3.start();
    }

    /**
     * 非线程安全的存款
     */
    private static void notSafeDeposit() {
        NotSafeBank bank = new NotSafeBank();
        Thread thread1 = new Thread(() -> bank.deposit(200), "jak");
        Thread thread2 = new Thread(() -> bank.deposit(200), "马云");
        Thread thread3 = new Thread(() -> bank.deposit(500), "马化腾");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
/**
 * 线程安全的银行
 */
class SafeBank {

    /**
     * 当前余额
     */
    private ThreadLocal<Integer> balance = ThreadLocal.withInitial(() -> 1000);

    /**
     * 存款
     *
     * @param money 存款金额
     */
    public void deposit(int money) {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " -> 当前账户余额为:" + this.balance.get());
        this.balance.set(this.balance.get() + money);
        System.out.println(threadName + " -> 存入 " + money + " 后,当前账户余额为:" + this.balance.get());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 非线程安全的银行
 */
class NotSafeBank {

    /**
     * 当前余额
     */
    private int balance = 1000;

    /**
     * 存款
     *
     * @param money 存款金额
     */
    public void deposit(int money) {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " -> 当前账户余额为:" + this.balance);
        this.balance += money;
        System.out.println(threadName + " -> 存入 " + money + " 后,当前账户余额为:" + this.balance);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

参考博客

### 回答1: threadlocal.withinitial是Java中ThreadLocal类的一个方法,它可以创建一个ThreadLocal对象,并指定一个初始值。当线程第一次访问该ThreadLocal对象时,会自动调用指定的初始值方法来获取初始值。这个方法可以方便地为每个线程创建一个独立的对象,避免了线程间的竞争和冲突。 ### 回答2: ThreadLocal.withInitial是Java中一个很有用的类,它可以帮助我们在线程间创建一些共享的对象,以保证线程安全。 ThreadLocal的作用是为每个线程提供一个独立的副本,线程间相互独立并不共享数据,因此可以保证线程安全,而ThreadLocal.withInitial方法就是用来为每个线程提供一个独立的初始值的。 首先,我们需要知道ThreadLocal的原理,每个线程拥有一个Map实例,Map的key为当前ThreadLocal实例,value为我们设置的值。当我们想要获取某个ThreadLocal的值时,线程会根据ThreadLocal的实例来获取对应的值,如果没有则会根据withInitial()方法提供的初始值进行初始化,并将其保存在Map中,以供以后使用。而因为每个线程都有一个Map实例,所以线程之间的数据是不共享的。 而ThreadLocal.withInitial方法就是用于为ThreadLocal设置一个初始值的,在使用ThreadLocal之前,我们需要设定一个初始值。我们可以通过withInitial方法来实现,这个方法接受一个Supplier类型的参数,即一个提供初始值的函数式接口。每个线程第一次访问ThreadLocal变量时,会用这个函数的返回值进行初始化。 总结来说,ThreadLocal.withInitial方法是为了确保每个线程都能有一个独立的初始值,保证线程之间的安全性,避免出现线程安全问题。所以,如果我们需要在线程间共享一些对象,同时又保证线程安全,就可以使用ThreadLocal.withInitial方法来实现。 ### 回答3: ThreadLocal.withInitial 是 Java 8 新增的 ThreadLocal 类中的一个静态方法。它的作用是为 ThreadLocal 对象设置一个初始值,也可以说是为每个线程都提供一个私有的变量副本。在多线程程序中,如果共享变量被多个线程使用会导致线程安全问题,使用 ThreadLocal.withInitial 可以很好地解决这个问题。 ThreadLocal.withInitial 方法有一个参数 Supplier,用于指定初始值的获取方式。Supplier 是一个函数式接口,定义了一个无参数的方法,用于返回一个值。 例如,以下代码创建了一个 ThreadLocal 对象,初始值为字符串 "initial value": ``` ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> "initial value"); ``` ThreadLocal.withInitial 方法创建的 ThreadLocal 对象,它会为每个线程都创建一个私有的变量副本,线程之间互不干扰。如果在一个线程中对 ThreadLocal 变量进行设置,不会影响其他线程的值,因为每个线程都有自己的副本。 ThreadLocal.withInitial 方法的不足之处在于,使用过程中要注意万无一失地释放资源,否则会导致内存泄漏等问题。因此,在使用 ThreadLocal 对象时,应该及时清理它所保留的线程私有变量,保证程序的正常运行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值