以下代码示例显示了一种常见方法,用于演示由于缺少发生之前关系而导致的并发问题。
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)
如果running是volatile,程序保证在大约一秒后终止。但是,如果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
我有一个运行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.
我尝试将最新提交的提交者日期设置为其作者日期。通常这适用于git rebase --committer-date-is-author-date HEAD~1. 不幸的是,只有一个承诺,这意味着我必须使用--root替代HEAD~1,但git rebase --committer-date-is-author-date --root不设置的提交日期作者日期出于某种原因。我能做什么?
我有一个接口A和B.A有一个叫做foo的(抽象)方法.B延伸A.
即使使用@Override,也可以在接口B中覆盖foo,但是在任何情况下都有意义吗?没有什么可以覆盖,因为这两种方法都必须是抽象的,没有正文.所以我猜没有合理的情况,对吧?
那么为什么可以在界面中覆盖呢?
我经常看到类的声明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) 我有一个功能界面
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) 我创建了一个名为 Region 的自己的类,并将 Region 的实例存储在 HashSet 中。我使用 HashSet,列表中没有相等的对象。Region 的字符串名称在 HashSet 中应该是唯一的,因此我重写了 equals 方法。
我的问题:
如果我将两个具有不同名称的区域存储到 HashSet 中,然后使不同的名称相等(通过名称的 setter),会发生什么?
这不是重复的。另一个问题是关于相等的 HashSet,而不是关于 HashSet 中的相等对象。
我有一个主线程和一个工作线程。主线程将任务添加到队列中,工作线程将其用于计算数据。在将对象放入队列之前,我在任务对象内的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) 我只是编写了这段代码来测试一些东西,以便更好地理解反射.
这是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) 考虑以下代码。
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
我的问题与这个基本相同,但这也适用于static函数吗?
我想了解:
static中的所有函数都视为?finalfinalfinal关键字有什么作用吗?staticfinal为什么不允许从子类构造函数设置受保护的最终字段?
例:
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 ×11
final ×2
interface ×2
author ×1
class ×1
collections ×1
commit ×1
concurrency ×1
constructor ×1
date ×1
declaration ×1
equals ×1
extends ×1
for-loop ×1
function ×1
generics ×1
getter ×1
git ×1
hashset ×1
lambda ×1
locking ×1
loops ×1
overriding ×1
performance ×1
protected ×1
rebase ×1
reflection ×1
set ×1
static ×1
subclass ×1
types ×1
volatile ×1