当前位置: 首页 > 知识库问答 >
问题:

多线程环境中的Volatile与static变量

冀鸿才
2023-03-14

我目前正在学习多线程,我发现了一些我无法解释的有趣的东西。据我所知,如果两个线程访问一个静态变量,它们可以将自己的副本复制到缓存中。Thread1对其本地缓存中的静态变量进行的更新不会反映在Thread2缓存的静态变量中。

java

 public class HashDecryptor {    

        private List<Thread> threads = new ArrayList<>();
        // some other fields

        public HashDecryptor() {            
            createThreads();
        }

        private void createThreads() {
            long max = (long) (Math.pow(26, numberOfChars));
            int n = numberOfThreads;
            for (int i = 0; i < n; ++i) {
                if (i == 0) {
                    threads.add(new Thread(new Cracker(hashToDecrypt, (max * i / n), (max * (i + 1) / n))));
                } else {
                    threads.add(new Thread(new Cracker(hashToDecrypt, (max * i / n) + 1, (max * (i + 1) / n))));
                }
            }
        }

        public void startDecryting() {
            for (Thread t : threads) {
                t.start();
            }
        }

    }

java

public class Cracker implements Runnable {

    // Some other fields

    private static boolean isFound;

    public Cracker(String hashToDecrypt, long start, long end) {
        this.hashToDecrypt = hashToDecrypt;
        this.start = start;
        this.end = end;
    }

    @Override
    public void run() {
        decrypt();
    }

    public void decrypt() {
        LocalTime startTime = LocalTime.now();
        long counter = start;
        while (!isFound && counter <= end) {
            if (match(counter)) {
                isFound = true;
                printData(generatePassword(counter), startTime);
            }
            counter++;
        }
    }   

}

共有1个答案

饶铭
2023-03-14

静态变量:在对象的上下文中使用,其中一个对象所做的更新将反映在同一类的所有其他对象中,但不在线程的上下文中使用,其中一个线程对静态变量的更新将立即反映到所有线程(在它们的本地缓存中)。如果两个线程(假设t1和t2)正在访问同一个对象并更新一个声明为静态的变量,那么这意味着t1和t2可以在各自的缓存中创建相同对象(包括静态变量)的本地副本,因此t1对本地缓存中静态变量的更新不会反映在t2缓存的静态变量中。

Volatile变量:如果两个线程(假设t1和t2)正在访问同一个对象并更新一个声明为Volatile的变量,那么这意味着t1和t2可以对该对象进行自己的本地缓存,但声明为Volatile的变量除外。因此volatile变量只有一个主副本,它将被不同的线程更新,一个线程对volatile变量的更新将立即反映到另一个线程。

 类似资料:
  • 问题内容: 说对所有对象而言值的一个副本和对所有线程而言值的一个副本是否正确? 无论如何,变量值也将成为所有线程的一个值,那么为什么要这样做呢? 问题答案: 在Java中声明一个静态变量,意味着将只创建一个副本,而不管该类创建了多少个对象。即使根本没有Objects创建,也可以访问该变量。但是,线程可能具有其本地缓存的值。 当变量是易变的而不是静态的时,每个变量将只有一个Object。因此,从表面

  • 我有几个问题。 > 如果我连续调用getSomeData(),是否每次都为stmt和rs分配新对象? 不管上面问题的答案如何,如果我在多线程环境中运行这段代码(使用MysqlUtils类的多线程),会不会因为我没有在getSomeData()中声明ResultSet rs而出现混淆?

  • 我的 Web 应用程序中出现随机错误,我迷路了。我创建了一个库来解码代码。我尝试了很多,从未失败过测试。但突然间,它开始随机失败。由于它在单线程测试中运行良好,有时在 servlet 环境中失败时,我能想象的唯一解释是问题与多线程环境中使用的库有关。老实说,我知道多线程是一个非常复杂的问题。我担心我的库可能不是线程安全的。顺便说一下,它非常简单,它是一个具有几种静态方法的正面类。基本上,假设您正在

  • 我在学习多线程时发现对象的速度变慢了。hashCode在多线程环境中,因为对于相同数量的对象,计算运行4个线程的默认哈希代码要比运行1个线程的默认哈希代码花费两倍的时间。 但根据我的理解,并行完成这项工作也需要类似的时间。 您可以更改线程数。每个线程都有相同的工作量,因此您希望在我的四核机器上运行4个线程可能需要与运行单个线程相同的时间。 我看到4x大约2.3秒,但是。1x为9秒。 我的理解是否有

  • 问题内容: 我正在尝试在多线程环境中对int变量进行经典的递增/递减。这是我的示例代码。 尽管我对所有三个线程都使用了join()方法,但结果仍然不一致。在这里加入不是意味着主线程要等到每个线程都完成执行吗?我什至尝试将同步添加到三个方法签名中的每个;但是我得到不一致的结果。 除了使用该变量的Atomic版本外,我还能如何确保始终获得0? 问题答案: 您的SyncCounter根本不是线程安全的。

  • 现在,他提出的下一个问题是为多线程环境编写单例类。然后,我写了双重检查单例类。 然后,他反对使用和双重检查,并说这是没用的。为什么要检查两次,为什么要使用synchronized?我试着用多种方案说服他。但是,他没有。 后来,我在家里尝试了下面的代码,在那里我使用了带有多个线程的简单的单例类。 那么,问题是,在多线程环境中是否有必要使用或/和双重检查方法?似乎我的第一个代码本身(没有添加任何额外的