Java8-ThreadLocal的Lambda构造方式:withInitial

本文介绍了Java8中ThreadLocal的withInitial构造方法,该方法利用Lambda表达式和Supplier接口创建ThreadLocal对象。通过一个银行存款的实例展示了ThreadLocal如何确保每个线程拥有独立的变量副本,避免并发问题。
摘要由CSDN通过智能技术生成

Java8中ThreadLocal对象提供了一个Lambda构造方式,实现了非常简洁的构造方法:withInitial。这个方法采用Lambda方式传入实现了 Supplier 函数接口的参数。写法如下:

代码实例

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

用ThreadLocal作为容器,当每个线程访问这个 balance 变量时,ThreadLocal会为每个线程提供一份变量副本,各个线程互不影响。

银行存款实例

附带一个银行存款的例子。

package me.zebe.cat.java.lambda;
 
/**
 * ThreadLocal的Lambda构造方式:withInitial
 *
 * @author Zebe
 */
public class ThreadLocalLambdaDemo {
 
    /**
     * 运行入口
     *
     * @param args 运行参数
     */
    public static void main(String[] args) {
        safeDeposit();
        //notSafeDeposit();
    }
 
    /**
     * 线程安全的存款
     */
    private static void safeDeposit() {
        SafeBank bank = new SafeBank();
        Thread thread1 = new Thread(() -> bank.deposit(200), "张成瑶");
        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), "张成瑶");
        Thread thread2 = new Thread(() -> bank.deposit(200), "马云");
        Thread thread3 = new Thread(() -> bank.deposit(500), "马化腾");
        thread1.start();
        thread2.start();
        thread3.start();
    }
 
}
 
/**
 * 非线程安全的银行
 */
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();
        }
    }
}
 
/**
 * 线程安全的银行
 */
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();
        }
    }
}
SafeBank情况下运行结果如下:

NotSafeBank情况下运行结果如下,发现红色方框内存款余额明显不对,因为余额这个初始变量没有被多个线程同步共享

今天的内容到此为止,欢迎各位网友留言交流一起学习进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易雪寒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值