相关疑难解决方法(0)

如何进入FutureTask执行状态?

我有一个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的所有可能的执行状态.

java multithreading futuretask executors

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

循环结束后程序未终止

在以下情况下,布尔值“ 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)

java

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

挥发性的目的/优点

您将使用volatile关键字的具体情况是什么?更重要的是:该计划如何从中受益?

从我已经阅读和了解到的内容:volatile应该用于不同线程访问的变量,因为它们比非易失性线程读取的速度稍快.如果是这样,是否应该有一个关键字强制执行相反的操作

或者他们实际上是在所有线程之间同步?正常变量怎么样?

我有很多多线程代码,我想稍微优化一下.当然我不希望获得巨大的性能提升(无论如何我都没有任何问题),但我总是试图让我的代码更好.我对这个关键字感到有些困惑.

java concurrency multithreading

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

java synchronized线程澄清

这个程序的答案必须在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 multithreading synchronized java-8

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

Java Timer挂起问题

我一直在试图弄清楚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)

java timer hang

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

在DCL的情况下需要volatile关键字

我只是在实践中阅读并发性.我开始知道有必要在双重检查锁定机制中使用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)

java concurrency multithreading volatile

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

为什么在返回之前将 volatile 分配给局部变量

在查看 android LiveData 的实现时,我偶然发现了以下代码片段

public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    }
Run Code Online (Sandbox Code Playgroud)

为什么要在返回之前将类成员分配给局部变量?我的猜测是它关系到一个事实,即mDatavolatile,但我不能完全理解我们为什么不能只return mData

java android volatile android-livedata

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

Java易失性并发

好的,我只是读了这个问题您是否曾在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 concurrency volatile

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

java中的volatile关键字真的与缓存有关吗?

从我读过的内容来看,java 中的“volatile”关键字确保线程始终获取特定指针的最新值,通常通过直接从/向内存读取/写入以避免缓存不一致。

但为什么需要这样做呢?据我所知,这已经在硬件级别上完成了。如果我从我的系统架构类中没有记错的话,更新内存位置的处理器核心会向其他处理器的缓存发送无效信号,迫使它们在需要时从内存中获取这些行。或者,如果情况相反——如果处理器获取内存,它将强制其他缓存的缓存(但未写入)行首先刷新到内存中。

我唯一的理论是,尽管我已经阅读了所有解释,但这实际上与缓存完全无关。它与 JVM 中的数据可以驻留在两个地方有关 - 线程的本地堆栈和堆。并且 Java 线程可以将其堆栈用作一种缓存。我会买那个,但这也意味着对驻留在堆上的数据使用 volatile 是无用的,因为它由所有线程共享并遵守硬件实现的一致性?

例如:

public final int[] is = new int[10];
Run Code Online (Sandbox Code Playgroud)

访问 is 的数据将始终导致获得最新的数据,因为数据驻留在堆上。然而,指针是一个原语,可能会成为堆栈问题的受害者,但由于它是最终的,我们没有这个问题。

我的假设正确吗?

编辑:据我所知,这不是重复的。所谓的重复线程是那些误导性的答案之一,它说它与缓存一致性有关。我的问题不是 volatile 用于什么,也不是如何使用它。它正在测试一种理论,并且进行更深入的测试。

java caching volatile

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

可变关键字线程安全

在谷歌搜索了很多之后,我发现了 volatile 关键字的多个定义。

概念一:

一些网站说,它是线程安全的,因为线程作用于存储 volatile 关键字的主内存,并在不将其拉到线程堆栈空间的情况下对其进行修改。

概念2:

有人说,它不是线程安全的,因为它会导致线程竞争条件。由于,线程将 volatile 变量拉到堆栈空间,修改它并立即将其放回主内存。但是,在另一个线程之间可以对 volatile 变量采取行动并采取行动。因此,通过这种方式,某些值会丢失。

哪个概念是正确的?

java multithreading volatile

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

Java - 线程和静态变量

刚开始使用 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

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

用一个小问题在java中终止一个线程

下面的代码是我尝试在不使用 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 multithreading

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