首页 > 其他分享 >第十四章《多线程》第9节:ThreadLocal类

第十四章《多线程》第9节:ThreadLocal类

时间:2023-01-02 18:32:32浏览次数:64  
标签:account Account maxValue ThreadLocal 线程 第十四章 多线程 属性

​如果多个线程共用一个对象,那么这个对象的属性值对于这些线程都是相同的。例如有一个a对象,它有一个x属性,如果x属性的值是1,那么对于任何一个线程而言,a对象的x属性都是1。但有些情况下,需要让一个对象的属性对于不同的线程具有不同的值,也就是说,a对象的x属性的值在一个线程那里是1,在另一个线程那里是2。

使用ThreadLocal类就能实现这样需求。如果对象的属性类型是Integer,那么可以在定义类时定义一个ThreadLocal类的对象,并且以指定ThreadLocal的类型参数为Integer,例如:​

class A{​
ThreadLocal<Integer> x = new ThreadLocal<Integer>();​
}​

以上代码中x属性就是一个ThreadLocal类对象,它的内部包装了一个Integer类对象,如果多个线程共享A类对象a,那么这个Integer的值可以在不同的线程中被指定为不同的值。这个ThreadLocal类定义的属性很有用处,例如有一个Account类表示账户,一个企业中,总经理能够一次性动用账户中一百万元,而副总经理只能一次性动用账户中的五十万元,那么Account中能够被动用的最大金额就可以用ThreadLocal类来定义,下面的【例14_20】就展示了ThreadLocal类的使用方法。​

【例14_20 ThreadLocal类】

Exam14_20.java​

class Account{
//能够动用的最大账户金额
ThreadLocal<Integer> maxValue = new ThreadLocal<Integer>();
Account(Integer maxValue){
this.maxValue.set(maxValue);
}
synchronized void printMaxValue(){
System.out.print(Thread.currentThread().getName());
System.out.println("能够动用的最大金额:"+maxValue.get());
}
}
class AccountThread extends Thread{
Account account;
Integer ownValue;//自身能动用的最大账户金额
AccountThread(String name,Account account,Integer ownValue){
super(name);
this.account = account;
this.ownValue = ownValue;
}
@Override
public void run() {
account.maxValue.set(ownValue);//①
account.printMaxValue();
}
}
public class Exam14_20 {
public static void main(String[] args) {
Account account = new Account(60000);
System.out.println("主线程中a对象的maxValue值:"+account.maxValue.get());
new AccountThread("总经理",account, 1000000).start();
new AccountThread("副总经理",account,500000).start();
}
}

【例14_20】中,Account类表示账户,账户最大可动用金额由maxValue属性来表示。可以看出:maxValue属性的类型是ThreadLocal,这个ThreadLocal类对象中包装了一个Integer对象,这个对象才是真正可动用的最大账户金额。main()方法中创建了一个Account类的对象account,并设置其maxValue属性的值为60000。以account为构造方法创建出的两个线程分别表示总经理和副总经理。这两个线程开始运行后首先设置自身可动用的最大金额为1000000和500000,之后再打印自身可动用金额的数值。【例14_20】的运行结果如图14-19所示。​

第十四章《多线程》第9节:ThreadLocal类_线程

图14-19【例14_20】运行结果​

从图14-19可以看出:每个线程中account的maxValue值各不相同。之所以能够做到同一个对象的相同属性具有不同的值,这是因为ThreadLocal类的属性在内存中为每个线程中都创建了副本,其中主线程也是一个线程,因此这个maxValue属性具有三个副本,分别属于主线程、总经理和副总经理。特别需要强调:只有在线程开始运行后,ThreadLocal类的属性才会被创建副本,因此语句①是在run()方法中设置每个线程的maxValue值而不是在Account构造方法中进行设置。如果程序员在构造方法中进行设置,那么不会出现maxValue的三个副本。

本文字版教程还配有更详细的视频讲解,小伙伴们可以点击这里观看。

标签:account,Account,maxValue,ThreadLocal,线程,第十四章,多线程,属性
From: https://blog.51cto.com/mugexuetang/5983951

相关文章

  • 第十四章《多线程》第4节:控制线程
    ​从14.3小节所列举的各个例子可以很明显的看出:线程的执行有一定的随机性,如果不加以适当控制,会导致执行结果的不确定性。实际开发过程中,很多情况下都需要让线程按照程序员期......
  • 第十四章《多线程》第5节:线程同步
    ​当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用,达到这个目的的过程叫做同步。如果线程在操作共享资源时没有实现同步,那么很有可......
  • 第十四章《多线程》第1节:线程基本原理
    ​计算机上可以运行程序,每一个正在运行着的程序都被称为“进程”,每个进程都拥有独立的系统资源以及地址空间,在没有进程允许的情况下,另一个用户进程不能访问这个进程的地址空......
  • 第十四章《多线程》第2节:线程的生命周期
    ​线程在被创建后会经历多个状态最后直至死亡,这个过程称为线程的“生命周期”。生命周期中包含很多状态,这些状态有:新生、就绪、运行、阻塞和死亡。线程有可能在几种状态之间......
  • 第十四章《多线程》第3节:创建线程
    ​Java语言中有一个专门表示线程的Thread类,这个类位于java.lang包下,因此在使用这个类时无需引入。Thread的方法定义了线程的基本操作,下面的表14-1展示了Thread类所定义的方......
  • java多线程
    1、线程:进程想要执行任务就需要依赖线程。换句话说,就是进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。 线程不能独立存在,必须依赖进程,在进程中运行每一个进......
  • 网络程序设计 实验3 多人聊天室 流式套接字 多线程编程
    实验3多人聊天室实验目的:通过流式套接字编程,及多线程编程,实现简单的多人聊天室。开发语言与工具:VC实验要求:1.使用MFC编程。2.利用流式套接字编程及多线程编程。3......
  • Linux 多线程原理深剖
    目录​​传统艺能......
  • 一次多线程并发查询导致结果混乱的问题的排查和记录·JAVA·2022
    业务背景该业务是报表查询类业务:要求从销售出库数据(存储于ElasticSearch索引中)中,按照管理者分组聚合查询各个管理者一定时间段内的动销汇总数据,如出库金额、毛利率等。但......
  • java 多线程并行执行任务 demo
    packagecom.sleep.demo;importorg.apache.commons.lang3.StringUtils;importjava.util.*;importjava.util.concurrent.*;importjava.util.concurrent.atomic.A......