我有一个singleThreadExecutor,以执行我按顺序提交给它的任务,即一个接一个的任务,没有并行执行.
我有runnable,这是这样的
MyRunnable implements Runnable {
@Override
public void run() {
try {
Thread.sleep(30000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
}
例如,当我向上述单线程执行程序提交三个MyRunnable实例时,我希望第一个任务执行,因为Thread.sleep在TIMED_WAITING中有执行线程(我可能错误的具体州).其他两个任务不应该分配线程来执行它们,至少在第一个任务完成之前.
所以我的问题是如何通过FutureTask API获取此状态或以某种方式到达执行任务的线程(如果没有这样的线程然后任务等待执行或挂起)并获得其状态或者可能由某些其他方式?
FutureTask只定义了isCanceled()和isDone()方法,但这些方法还不足以描述Task的所有可能的执行状态.
在以下情况下,布尔值“ done”被设置为true,这将结束程序。相反,即使while(!done)不再是有效的情况,该程序仍会继续运行,因此它应该已停止。现在,如果我要添加一个线程睡眠,即使睡眠时间为零,程序也会按预期终止。这是为什么?
public class Sample {
private static boolean done;
public static void main(String[] args) throws InterruptedException {
done = false;
new Thread(() -> {
System.out.println("Running...");
int count = 0;
while (!done) {
count++;
try {
Thread.sleep(0); // program only ends if I add this line.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(2000);
done = true; // this is set to true after 2 seconds so program should end.
System.out.println("Done!"); // this gets printed after 2 seconds …Run Code Online (Sandbox Code Playgroud) 您将使用volatile关键字的具体情况是什么?更重要的是:该计划如何从中受益?
从我已经阅读和了解到的内容:volatile应该用于不同线程访问的变量,因为它们比非易失性线程读取的速度稍快.如果是这样,是否应该有一个关键字强制执行相反的操作?
或者他们实际上是在所有线程之间同步?正常变量怎么样?
我有很多多线程代码,我想稍微优化一下.当然我不希望获得巨大的性能提升(无论如何我都没有任何问题),但我总是试图让我的代码更好.我对这个关键字感到有些困惑.
这个程序的答案必须在5秒后完成"改变完成",但我得到"改变完成"和"完成".我没有getDone方法同步.我有什么想法为线程完成处理.
public class Main {
private static boolean done = false;
private static int count;
public static void main(String[] args)throws InterruptedException {
new Thread(() -> {
while (!getDone()) {
count = count + 1;
}
System.out.println("DONE!!!!");
}).start();
Thread.sleep(5000);
System.out.println("Changing done");
synchronized (Main.class) {
done = true;
}
}
public static boolean getDone() {
return done;
}
}
Run Code Online (Sandbox Code Playgroud) 我一直在试图弄清楚Java Timers的问题.我想知道这里是否有人可以提供帮助.任何诊断问题的帮助都非常感谢.
我有一个带有三个TimerTask类(A,B和Stopper)的简单程序.A和B分别每400ms和500ms重复运行一次.Stopper任务计划在2秒运行以关闭所有内容.定时器按预期触发,任务的run()方法按预期执行.但是,一旦执行了止动任务,我希望程序终止,但它只是在打印"所有任务和计时器取消,退出"后挂起.我已经尝试过使用jstack来诊断问题,但没有任何明显的东西可以表明什么,如果需要释放/停止/取消等等.
这是我的代码:
package com.example.experiments;
import java.util.Date;
/**
* A test timer class to check behavior of exit/hang issues
*/
public class TimerTest {
TimerTest(){
}
class TaskA extends java.util.TimerTask {
TaskA(){
}
public void run() {
System.err.println("A.run() called.");
if (!running){
System.err.println("A: calling this.cancel().");
this.cancel();
return;
}
}
public boolean cancel(){
System.err.println("Canceling TaskA");
return super.cancel();
}
}
class TaskB extends java.util.TimerTask {
TaskB(){
}
public void run(){
System.err.println("B.run() called.");
if (!running){
System.err.println("B: calling this.cancel().");
this.cancel();
return;
}
}
public …Run Code Online (Sandbox Code Playgroud) 我只是在实践中阅读并发性.我开始知道有必要在双重检查锁定机制中使用volatile关键字,否则线程可以读取非空对象的失效值.因为它可以在不使用volatile关键字的情况下重新排序指令.由于该对象引用可以在调用构造函数之前分配给资源变量.所以线程可以看到部分构造的对象.
我有一个问题.
我假设synchronized块也限制编译器从指令重新排序,那么为什么我们需要volatile关键字呢?
public class DoubleCheckedLocking {
private static volatile Resource resource;
public static Resource getInstance() {
if (resource == null) {
synchronized (DoubleCheckedLocking.class) {
if (resource == null)
resource = new Resource();
}
}
return resource;
}
}
Run Code Online (Sandbox Code Playgroud) 在查看 android LiveData 的实现时,我偶然发现了以下代码片段
public T getValue() {
Object data = mData;
if (data != NOT_SET) {
return (T) data;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
为什么要在返回之前将类成员分配给局部变量?我的猜测是它关系到一个事实,即mData是volatile,但我不能完全理解我们为什么不能只return mData。
好的,我只是读了这个问题您是否曾在Java中使用volatile关键字?,我使用volatile变量来停止循环.我也看过这个参考资料,http://www.javamex.com/tutorials/synchronization_volatile.shtml.现在文章说波动变量是非阻塞的.它还说它不能用于读取 - 更新 - 写入序列中的并发.这是有道理的,因为它们是非阻塞的.
因为从不缓存volatile变量,所以简单地使用同步来停止循环(来自早期链接)会更快吗?
编辑:使用同步解决方案
public class A{
private boolean test;
public A(){
test = true;
}
public synchronized void stop(){
test = false;
}
public synchronized boolean isTrue(){
return test;
}
}
public class B extends Thread {
private A a;
public B(A refA){
a = refA;
}
public void run(){
//Does stuff here
try{
sleep(1000);
}
catch(Exception e){}
a.stop();
}
public static void main(String [] args){
A TestA = new A();
B …Run Code Online (Sandbox Code Playgroud) 从我读过的内容来看,java 中的“volatile”关键字确保线程始终获取特定指针的最新值,通常通过直接从/向内存读取/写入以避免缓存不一致。
但为什么需要这样做呢?据我所知,这已经在硬件级别上完成了。如果我从我的系统架构类中没有记错的话,更新内存位置的处理器核心会向其他处理器的缓存发送无效信号,迫使它们在需要时从内存中获取这些行。或者,如果情况相反——如果处理器获取内存,它将强制其他缓存的缓存(但未写入)行首先刷新到内存中。
我唯一的理论是,尽管我已经阅读了所有解释,但这实际上与缓存完全无关。它与 JVM 中的数据可以驻留在两个地方有关 - 线程的本地堆栈和堆。并且 Java 线程可以将其堆栈用作一种缓存。我会买那个,但这也意味着对驻留在堆上的数据使用 volatile 是无用的,因为它由所有线程共享并遵守硬件实现的一致性?
例如:
public final int[] is = new int[10];
Run Code Online (Sandbox Code Playgroud)
访问 is 的数据将始终导致获得最新的数据,因为数据驻留在堆上。然而,指针是一个原语,可能会成为堆栈问题的受害者,但由于它是最终的,我们没有这个问题。
我的假设正确吗?
编辑:据我所知,这不是重复的。所谓的重复线程是那些误导性的答案之一,它说它与缓存一致性有关。我的问题不是 volatile 用于什么,也不是如何使用它。它正在测试一种理论,并且进行更深入的测试。
在谷歌搜索了很多之后,我发现了 volatile 关键字的多个定义。
概念一:
一些网站说,它是线程安全的,因为线程作用于存储 volatile 关键字的主内存,并在不将其拉到线程堆栈空间的情况下对其进行修改。
概念2:
有人说,它不是线程安全的,因为它会导致线程竞争条件。由于,线程将 volatile 变量拉到堆栈空间,修改它并立即将其放回主内存。但是,在另一个线程之间可以对 volatile 变量采取行动并采取行动。因此,通过这种方式,某些值会丢失。
哪个概念是正确的?
刚开始使用 java 中的线程,我无法解释程序的输出
public class ThreadExample extends Thread{
private int info;
static int x = 0;
public ThreadExample (int info) {
this.info = info;
}
public void run () {
if ( info == 1 ) {
x = 3;
System.out.println(Thread.currentThread().getName() + " " + x);
} else{
x = 1;
System.out.println(Thread.currentThread().getName() + " " + x);
}
}
public static void main (String args []) {
ThreadExample aT1 = new ThreadExample(1);
ThreadExample aT2 = new ThreadExample(2);
aT1.start();
aT2.start();
System.err.println(x); …Run Code Online (Sandbox Code Playgroud) java multithreading static-variables thread-sleep java-threads
下面的代码是我尝试在不使用 stop() 的情况下停止我创建的线程。但是,该线程似乎在停止后会再次执行。我想知道为什么会这样?另外:如果我将迭代从 100 更改为 10,则它可以正常工作。谁能帮我解决这个问题?提前致谢!
public class TerminateThread implements Runnable{
private boolean flag = true;
public TerminateThread(String name) {
this.name = name;
}
private String name;
public void run() {
int i = 0;
while(flag) {
System.out.println(name+"--->"+i++);
}
}
public void Terminate() {
this.flag = false;
}
public static void main(String[] args) {
TerminateThread tt = new TerminateThread("Thread");
new Thread(tt).start();
for (int i = 0; i <= 100; i++) {
if (i == 88) {
tt.Terminate();
System.out.println("Thread terminated!!!");
} …Run Code Online (Sandbox Code Playgroud) java ×12
volatile ×5
concurrency ×3
android ×1
caching ×1
executors ×1
futuretask ×1
hang ×1
java-8 ×1
java-threads ×1
synchronized ×1
thread-sleep ×1
timer ×1