小编sto*_*r96的帖子

如果不需要该值,Java 是否允许优化掉易失性读取,同时删除同步之前发生的操作?

以下代码示例显示了一种常见方法,用于演示由于缺少发生之前关系而导致的并发问题。

private static /*volatile*/ boolean running = true;
    
public static void main(String[] args) throws InterruptedException {
    new Thread() {
        @Override
        public void run() {
            while (running) {
                // Do nothing
            }
        }
    }.start();
    Thread.sleep(1000);
    running = false;
}
Run Code Online (Sandbox Code Playgroud)

如果runningvolatile,程序保证在大约一秒后终止。但是,如果running不是volatile,则根本无法保证程序终止(因为在running这种情况下没有发生之前关系或保证变量更改的可见性),而这正是我的测试中发生的情况。

根据JLS 17.4.5,人们还可以通过写入和读取另一个volatile变量来强制执行发生前关系running2,如以下代码示例所示。

private static boolean running = true;
private static volatile boolean running2 = true;
    
public static void main(String[] args) throws InterruptedException {
    new Thread() …
Run Code Online (Sandbox Code Playgroud)

java multithreading volatile java-memory-model happens-before

16
推荐指数
1
解决办法
555
查看次数

Java在for循环中使用getter还是创建局部变量?

我有一个运行4096次的for循环,它应该尽可能快.性能在这里非常重要.目前我在循环中使用getter方法,它只返回在循环进行时不会改变的字段中的值或对象.

例:

for (;;) {
    doSomething(example.getValue());
}
Run Code Online (Sandbox Code Playgroud)

使用getter是否有任何开销?使用以下方式更快吗?

例:

Object object = example.getValue();
for (;;) {
    doSomething(object);
}
Run Code Online (Sandbox Code Playgroud)

如果是,那么访问公共领域是否也是如此example.value

编辑:我不在System.out.println()循环内部使用.

编辑:某些字段不是final.没有字段,volatile也没有方法(getter)synchronized.

java getter performance loops for-loop

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

git rebase --committer-date-is-author-date --root 不起作用

我尝试将最新提交的提交者日期设置为其作者日期。通常这适用于git rebase --committer-date-is-author-date HEAD~1. 不幸的是,只有一个承诺,这意味着我必须使用--root替代HEAD~1,但git rebase --committer-date-is-author-date --root不设置的提交日期作者日期出于某种原因。我能做什么?

git author date commit rebase

11
推荐指数
3
解决办法
7460
查看次数

覆盖接口中的方法是否有意义

我有一个接口A和B.A有一个叫做foo的(抽象)方法.B延伸A.

即使使用@Override,也可以在接口B中覆盖foo,但是在任何情况下都有意义吗?没有什么可以覆盖,因为这两种方法都必须是抽象的,没有正文.所以我猜没有合理的情况,对吧?

那么为什么可以在界面中覆盖呢?

java extends overriding interface

9
推荐指数
2
解决办法
142
查看次数

是否为HashSet或其他实现使用Java变量类型Collection?

我经常看到类的声明List<String> list = new ArrayList<>();Set<String> set = new HashSet<>();类的声明。对我来说,使用变量类型的接口来提供实现的灵活性是非常有意义的。上面的示例仍然定义Collection了必须使用的类型,分别允许的操作以及在某些情况下的行为(由于docs)。

现在考虑以下情况:使用类中的字段实际上仅需要Collection(或什至Iterable)接口的功能,Collection而实际上的类型无关紧要,或者我不想对其进行过多说明。因此,我选择例如HashSet作为实现,并将字段声明为Collection<String> collection = new HashSet<>();

那么,Set在这种情况下,该字段实际上是否应该是类型?这样的声明是不好的做法吗,如果是这样,为什么?还是最好的做法是指定尽可能少的实际类型(并仍然提供所有必需的方法)。之所以这样问,是因为我几乎从未见过这样的声明,而最近在只需要指定Collection接口功能的情况下,我会得到更多的信息。

例:

// Only need Collection features, but decided to use a LinkedList
private final Collection<Listener> registeredListeners = new LinkedList<>();

public void init() {
    ExampleListener listener = new ExampleListener();
    registerListenerSomewhere(listener);
    registeredListeners.add(listener);
    listener = new ExampleListener();
    registerListenerSomewhere(listener);
    registeredListeners.add(listener);
}

public void reset() {
    for (Listener listener : …
Run Code Online (Sandbox Code Playgroud)

java collections types interface declaration

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

Java Lambda 表达式和对泛型方法的方法引用

我有一个功能界面

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;

@FunctionalInterface
public interface SubmitterCompletable extends Submitter {
    @Override
    <T> CompletableFuture<T> submit(Callable<T> task);
}
Run Code Online (Sandbox Code Playgroud)

和两个函数

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

public final class CompletableFutureUtils {
    public static <U> CompletableFuture<U> runAsync(Callable<U> callable) {
        // ...
    }

    public static <U> CompletableFuture<U> runAsync(Callable<U> callable, Executor executor) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我想SubmitterCompletable使用 lambda 表达式或方法引用从这些函数创建 s。第一个通过使用方法引用工作得很好。

SubmitterCompletable submitterCompletable = CompletableFutureUtils::runAsync;
Run Code Online (Sandbox Code Playgroud)

然而,对于第二个,我必须使用 lambda 表达式来传递 an Executor,但它不起作用。

Executor executor = /* ... */;
SubmitterCompletable submitterCompletable = c -> …
Run Code Online (Sandbox Code Playgroud)

java generics lambda functional-interface method-reference

5
推荐指数
1
解决办法
619
查看次数

如果我更改 HashSet 内的对象会发生什么?

我创建了一个名为 Region 的自己的类,并将 Region 的实例存储在 HashSet 中。我使用 HashSet,列表中没有相等的对象。Region 的字符串名称在 HashSet 中应该是唯一的,因此我重写了 equals 方法。

我的问题:

如果我将两个具有不同名称的区域存储到 HashSet 中,然后使不同的名称相等(通过名称的 setter),会发生什么?

这不是重复的。另一个问题是关于相等的 HashSet,而不是关于 HashSet 中的相等对象。

java equals set hashset

4
推荐指数
1
解决办法
206
查看次数

Java在不同的线程上锁定和解锁

我有一个主线程和一个工作线程。主线程将任务添加到队列中,工作线程将其用于计算数据。在将对象放入队列之前,我在任务对象内的ReentrantLock对象(在主线程上调用锁。当工作线程完成了从队列中处理任务的工作后,我称解锁(在工作线程上)。问题是我收到一个IllegalMonitorStateException,因为我在不同的线程上调用了锁定和解锁。

我正在寻找可以在不同线程上执行此操作的替代锁定系统。

例:

public class Worker extends Thread {
    public static Queue<Task> tasks = new ConcurrentLinkedQueue<Task>();

    @Override
    public void run() {
        while (true) {
            Task task = tasks.poll();

            if (task != null) {
                task.work();
                task.lock.unlock(); // Here is the unlock, Task#i should not change up to now
            }
        }
    }
}


public class Task {
    private int i = 0;
    public Lock lock;

    public void setI(int i) {
        lock.lock();
        this.i = i;
        lock.unlock();
    } …
Run Code Online (Sandbox Code Playgroud)

java multithreading locking reentrantlock

4
推荐指数
1
解决办法
1903
查看次数

Java反射无法按预期工作

我只是编写了这段代码来测试一些东西,以便更好地理解反射.

这是ReflectionTestMain类:

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTestMain {
    public static void main(String[] args) {
        try {
            ReflectionTest rt = new ReflectionTest();
            Class<ReflectionTest> c = ReflectionTest.class;
            Field f = c.getDeclaredField("value");
            f.setAccessible(true);
            f.set(rt, "text");
            Method m = c.getDeclaredMethod("getValue");
            m.setAccessible(true);
            String value = (String) m.invoke(rt);
            System.out.println(value);
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是ReflectionTest类.

public class ReflectionTest {
    private final String value = "test";

    private String getValue() …
Run Code Online (Sandbox Code Playgroud)

java reflection

3
推荐指数
1
解决办法
94
查看次数

Java 发生在关系之前?

考虑以下代码。

public class Test {
    private boolean running = false;

    public void run() {
        running = true;
    }

    public void test() {
        boolean running1 = running;
        boolean running2 = running;
        System.out.println("running1: " + running1);
        System.out.println("running2: " + running2);
    }
}
Run Code Online (Sandbox Code Playgroud)

线程 A 调用run(),然后另一个线程 B 调用test()并且不应该有任何发生之前的关系。我知道不能保证线程 B 看到线程 A 所做的更改。但是这个程序的输出有没有可能是:

running1: true
running2: false
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading thread-safety happens-before

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

最终类中的静态函数是否隐式最终?

我的问题与这个基本相同,但这也适用于static函数吗?

我想了解:

  1. 编译器是否将类static中的所有函数都视为?finalfinal
  2. 在类中的函数中添加final关键字有什么作用吗?staticfinal

java static final class function

0
推荐指数
1
解决办法
1119
查看次数

Java为什么不允许从子类构造函数设置受保护的最终字段?

为什么不允许从子类构造函数设置受保护的最终字段?

例:

class A {
    protected final boolean b;

    protected A() {
        b = false;
    }
}

class B extends A {
    public B() {
        super();
        b = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为在某些情况下会有意义,不是吗?

java constructor final protected subclass

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