相关疑难解决方法(0)

Java线程和垃圾收集器

可能重复:是否
收集了Java Thread Garbage

考虑以下课程:

class Foo implements Runnable {

  public Foo () {
       Thread th = new Thread (this);
       th.start();
  }

  public run() {
    ... // long task
  }

}
Run Code Online (Sandbox Code Playgroud)

如果我们创建几个实例Foo

new Foo();
new Foo();
new Foo();
new Foo();
Run Code Online (Sandbox Code Playgroud)

(请注意,我们没有指向它们的指针).

  1. 在线程结束之前,垃圾收集器是否可以删除这些实例run()?(换句话说:是否有Foo对象的引用?)

  2. 而且,另一方面,在`run()'中的线程结束后,或者我们是否在浪费内存("内存泄漏")后,GC会删除这些实例吗?

  3. 如果1.或2.是问题,那么正确的方法是什么?

谢谢

java multithreading garbage-collection

20
推荐指数
3
解决办法
7716
查看次数

在链接构造函数时,JVM的隐式内存屏障如何表现?

参考我之前关于不完整构造对象的问题,我有第二个问题.正如Jon Skeet指出的那样,在构造函数的末尾有一个隐式的内存障碍,可以确保final所有线程都可以看到这些字段.但是如果构造函数调用另一个构造函数呢?在每个人的最后是否有这样的记忆障碍,或者只是在第一个被召唤的人的最后?也就是说,当"错误"解决方案是:

public class ThisEscape {
    public ThisEscape(EventSource source) {
        source.registerListener(
            new EventListener() {
                public void onEvent(Event e) {
                    doSomething(e);
                }
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

正确的一个是工厂方法版本:

public class SafeListener {
    private final EventListener listener;

    private SafeListener() {
        listener = new EventListener() {
            public void onEvent(Event e) {
                doSomething(e);
            }
        }
    }

    public static SafeListener newInstance(EventSource source) {
        SafeListener safe = new SafeListener();
        source.registerListener(safe.listener);
        return safe;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下工作是否也会起作用?

public class MyListener {
    private final EventListener listener;

    private …
Run Code Online (Sandbox Code Playgroud)

java constructor jvm compiler-optimization memory-barriers

14
推荐指数
1
解决办法
1291
查看次数

Java:通过_happens-before_ relation安全地在构造函数中"泄漏"最终类的引用?

Goetz的"Java Concurrency in Practice"第3.2.1节包含以下规则:

this在施工期间不要让参考物逃逸

我的理解是,在一般情况下,允许this以逃避可能导致其他线程看到您的对象不完全构建版本和违反的初始化安全保障final领域(如讨论如这里)

但是有可能安全泄漏this吗?特别是,如果你happen-before在泄漏之前建立关系?

例如,官方执行官Javadoc

在将Runnable对象提交到一个Executor 发生之前的一个线程中的操作- 在它执行开始之前,可能在另一个线程中

我对Java内存模型的天真阅读理解是,类似下面的内容应该是安全的,即使它this在构造函数结束之前泄漏:

public final class Foo {
  private final String str1;
  private String str2;
  public Foo(Executor ex) {
    str1 = "I'm final";
    str2 = "I'm not";
    ex.execute(new Runnable() {
      // Oops: Leakage!
      public void run() { System.out.println(str1 + str2);}
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,即使我们已经泄漏this到潜在的恶意Executor,泄漏 …

java multithreading

14
推荐指数
1
解决办法
486
查看次数

Java中有ImmutableBitSet吗?

是否有任何Java库提供ImmutableBitSet?我没有找到任何,也没有发现Guava也没有使用谷歌.

java collections guava

11
推荐指数
2
解决办法
2298
查看次数

最终字段如何阻止其他线程看到部分构造的对象?

我正在研究创建一个具有final字段的不可变数据类型(包括在分配给最终成员字段之前构造和填充的数组),并注意到似乎指定了JVM以保证获得的任何其他线程对此对象的引用将看到初始化的字段和数组值(假设没有指针this在构造函数中发布,请参阅什么是"未完成构造的对象"?以及JVM的隐式内存屏障在链接构造函数时如何表现?).

我很好奇如何在不同步每个访问此对象的情况下实现此目的,或者以其他方式支付一些重要的性能损失.根据我的理解,JVM可以通过执行以下操作来实现此目的:

  1. 在构造函数的末尾发出写入围栅
  2. 仅在写入围栏之后发布对新对象的引用
  3. 每次引用对象的最终字段时都会发出读取栅栏

我想不出更简单或更便宜的方法来消除其他线程看到未初始化的最终字段(或通过最终字段的递归引用)的风险.

由于读取对象的其他线程中的所有读取栅栏,这似乎可能会造成严重的性能损失,但是消除读取栅栏会导致在发出读取之前在另一个处理器中看到对象引用的可能性.栅栏或以其他方式看到对应于新初始化的最终字段的存储器位置的更新.

有谁知道这是如何工作的?这是否会带来显着的性能损失?

java concurrency

8
推荐指数
1
解决办法
285
查看次数

以线程安全方式创建对象

直接来自这个网站,我遇到了关于创建对象线程安全性的以下描述.

警告:构造将在线程之间共享的对象时,要非常小心,对对象的引用不会过早"泄漏".例如,假设您要维护一个包含每个类实例的List调用实例.您可能想要将以下行添加到构造函数中:

instances.add(本);

但是其他线程可以在构造对象完成之前使用实例来访问对象.

是否有人能够用其他词语或其他更可抓住的例子来表达相同的概念?

提前致谢.

java concurrency multithreading

5
推荐指数
2
解决办法
1379
查看次数

为什么类结构语言中的构造函数通常被视为线程安全?

(我希望我可以为实现线程的所有类构造语言标记这个问题,但是这里有Java,C++,C#和Ruby.不是我对所有这些都很酷)

我想我已经在博客文章/教程上看到过这种效果的陈述(类构造函数是线程安全的).我无法追踪任何直接的陈述,但许多帖子和教程都做出了假设,或者甚至没有提到在构造函数和析构函数上运行的线程问题.坚持Java,它有一个历史和一些正式的多线程方法,

Javamex

扬科夫的教程

Oracle教程

所有这些文章/网页都以自信的方式编写,并包含全面的讨论.他们都提到了方法同步的Java特性,所以你希望他们可能会提到这会如何影响构造和破坏的特殊方法.但他们没有.

但类构造函数和析构函数需要像任何类方法一样考虑.这是一篇关于Java的文章,

Java中的安全构造技术

关于从构造函数泄漏'this'引用.这里有几个StackOverflow帖子,

Java中不完整构造的对象,

Java构造函数需要锁定

显示具有线程问题的构造函数.我怀疑特殊方法中的线程问题仅限于Java.

所以,我想知道,

  • 是否基于构造函数的总体布局假设了线程安全(无论如何定义)?一个代码不多的紧密编码的构造函数将接近可重入代码(通过参数接受数据等)

  • 或者口译员/编制者是否处理具有特殊待遇或保护的施工人员/破坏者?例如,Java内存模型在构造结束时对期望做出一些评论,我希望其他语言规范也是如此.

维基百科关于构造函数的内容很少.在不同的上下文中,这篇文章中的构造语言中的构造函数包含一些提示,但不是关于线程安全性.

虽然在专业书籍中有许多信息,但是对StackOverflow进行一般性(尽管语言特定的提及很有趣!)解释/讨论会很好.

c# c++ ruby java

2
推荐指数
1
解决办法
134
查看次数