有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java本地线程的用途和需求是什么

我正在探索Java中的本地线程。我不明白为什么我们需要这门课。如果我只是简单地将一个新对象传递给每个线程执行,就像使用initialValue()时发生的一样,我可以达到同样的目的。我只是为initialvalue()中的每个线程返回一个新对象

但是假设我有两个线程,ThreadOne:A和ThreadTwo B。现在我想让它们拥有自己的SimpleDataFormat类的副本。我可以通过在ThreadLocal类中扭曲SimpleDataFormat的对象,然后使用initialValue()返回新的SimpleDataFormat(“yyyyMMdd HHmm”);来实现这一点;。通过创建SimpleDateFormat和p两个新对象,我可以达到同样的目的[ThreadOne:A和ThreadTwo:B各分配一个。ThreadLocal如何额外帮助我

问候,


共 (4) 个答案

  1. # 1 楼答案

    您将使用ThreadLocal将“数据”传递给特定的线程
    例如,您有一个方法doSomething(SomeObject a, SomeOtherObject b);
    您可以通过线程局部变量,而不仅仅是ab,以线程安全的方式为特定的执行线程向此方法传递更多信息

  2. # 2 楼答案

    线程本地存储用于单个线程上下文中的全局变量

    考虑这个例子:编写一个多线程程序来处理用户请求。多个用户可以同时发起请求;您的系统为每个用户使用一个线程

    当用户请求到达时,您的系统会找出它来自的用户,并为该用户创建UserPermissions对象的实例

    有几种方法可以使该对象对正在运行的程序可用。一种方法是将UserPermissions传递给可能需要它的每个方法,以及直接或间接调用可能需要它的方法的每个方法。这可能有问题,尤其是在使用回调的上下文中

    如果您的程序不是多线程的,您应该在一个全局变量中设置UserPermissions。不幸的是,您不能这样做,因为多个用户请求可能同时处于活动状态

    这就是线程本地存储的作用:创建用户权限的进程在线程本地存储中设置UserPermissions对象,并将其留在那里,直到请求处理结束。这样,所有方法都可以根据需要获取UserPermissions,而不必将它们作为方法参数传递

  3. # 3 楼答案

    对于你的问题,已经有一些很好的例子了

    但我试图解释第二部分:

    But say i have two threads, ThreadOne: A and ThreadTwo B. Now I want them to have a copy of own of say SimpleDateFormat class. I can do this by warping the object of SimpleDateFormat in a ThreadLocal Class and then using initialValue() I can return new SimpleDateFormat("yyyyMMdd HHmm");. Same motive I can achieve by creating two new Objects of SimpleDateFormat and p[assing one each to ThreadOne : A. and ThreadTwo : B. How does ThreadLocal help me extra

    通常,您需要使用某种格式格式化日期,当然最好只创建一次SimpleDateFormat对象(而不是每次需要格式化日期时都创建一个新的SimpleDateFormat

    所以你可能会有这样的想法:

    public class DateUtils {  
        private final static DateFormat dateFormat = new SimpleDateFormat("dd-mm-yyyy");  
    
        public String formatDate(Date date) {  
            return dateFormat.format(date);  
        }  
    }  
    

    如果多个线程同时调用formatDate(...)(您可能会得到奇怪的输出或exceptions),这将失败,因为SimpleDateFormat不是Thread-Safe。要使其线程安全,可以使用ThreadLocal

    public class DateUtils {  
        private final ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() {  
            @Override  
            protected DateFormat initialValue() {  
                return new SimpleDateFormat("dd-mm-yyyy");  
            }  
        };  
    
        public String formatDate(Date date) {  
            return dateFormat.get().format(date);  
        }  
    }  
    

    现在,对formatDate()方法的每个线程(或调用)都将在本地副本上工作,并且不会相互干扰。这将为您提供线程安全行为

  4. # 4 楼答案

    本地线程是实现dynamic scoping的廉价方法。使用动态作用域,在代码块求值期间存在绑定。在这种情况下,绑定存在于特定线程的执行过程中。早期的lisps支持动态作用域,但它很少有意义,所以大多数现代编程语言不支持它,除非通过线程局部变量

    动态作用域/线程局部变量有助于维护周围的普遍上下文信息,例如:

    有一种叫做“context-oriented programming”的研究方法,旨在更好地支持编程语言中的这种关注。文件“context-oriented programming: beyond layers”显示了一些进一步的例子