我正在尝试通过CompletableFuture.supplyAsync将优先级队列添加到使用ThreadPoolExecutor和LinkedBlockingQueue的现有应用程序.问题是我无法想出一个设计来分配我可以在PriorityBlockingQueue的Comparator中访问的任务优先级.这是因为我的任务被CompletableFuture包装到一个名为AsyncSupply的私有内部类的实例中,该实例隐藏了私有字段中的原始任务.然后使用这些AsteSupply对象作为Runnables调用Comparator,如下所示:
public class PriorityComparator<T extends Runnable> implements Comparator<T> {
@Override
public int compare(T o1, T o2) {
// T is an AsyncSupply object.
// BUT I WANT SOMETHING I CAN ASSIGN PRIORITIES TOO!
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
我调查了扩展CompletableFuture的可能性,因此我可以将它包装在一个不同的对象中,但很多CompletableFuture被封装且不可用.因此,扩展它似乎不是一种选择.也没有用适配器封装它,因为它实现了非常宽的接口.
除了复制整个CompletableFuture并修改它之外,我不确定如何解决这个问题.有任何想法吗?
java executorservice threadpoolexecutor java-threads completable-future
当已经运行的任务之一抛出异常时,我需要取消所有已调度但尚未运行的CompletableFuture任务.
尝试以下示例,但大多数情况下main方法不会退出(可能是由于某种类型的死锁).
public static void main(String[] args) {
ExecutorService executionService = Executors.newFixedThreadPool(5);
Set< CompletableFuture<?> > tasks = new HashSet<>();
for (int i = 0; i < 1000; i++) {
final int id = i;
CompletableFuture<?> c = CompletableFuture
.runAsync( () -> {
System.out.println("Running: " + id);
if ( id == 400 ) throw new RuntimeException("Exception from: " + id);
}, executionService )
.whenComplete( (v, ex) -> {
if ( ex != null ) {
System.out.println("Shutting down.");
executionService.shutdownNow();
System.out.println("shutdown.");
}
} …Run Code Online (Sandbox Code Playgroud) 我想知道在以下情况下会发生什么:
创建了两个线程:
Thread t1 = new Thread();
Thread t2 = new Thread();
Run Code Online (Sandbox Code Playgroud)
假设这些只是打印出一个字符串,然后线程调用 .start() 方法:
t1.start();
t2.start():
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么这些线程每次都以看似随机的顺序打印?我知道线程是并发执行的,但由于主进程的顺序执行,线程t1不会总是先完成?t2
无论有没有volatile关键字,我都会得到相同的输出。
我在代码中犯了错误吗?
public class MutliThreadExample extends Thread{
volatile int value;
public static void main(String[] args) throws InterruptedException {
MutliThreadExample thread1 = new MutliThreadExample();
MutliThreadExample thread2 = new MutliThreadExample();
thread1.start();
thread1.join();
thread2.start();
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
value = value + 1;
System.out.println(value + "-" + Thread.currentThread());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我无法volatile在 Java 中正确使用关键字。
什么是实例化之间的差异(如果有的话)螺纹这样
SomeThread t = new SomeThread();
t.start();
Run Code Online (Sandbox Code Playgroud)
和这样:
new SomeThread().start();
Run Code Online (Sandbox Code Playgroud)
将在构造函数中类SomeThread仍然被实例化?
或者它实际上是第二次跳过实例化构造函数并直接进入run() -方法?
注意:SomeThread类扩展了Thread
在这里,我试图在线程终止后加入该线程,代码工作正常,但我的问题是它不应该抛出一些错误消息或任何信息吗?
public class MultiThreadJoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new MultiThreadJoinTest());
a.start();
Thread.sleep(5000);
System.out.println("Begin");
System.out.println("End");
a.join();
}
public void run() {
System.out.println("Run");
}
}
Run Code Online (Sandbox Code Playgroud) 我需要这个可以访问相同数据的线程同时执行而不会相互混淆,所以Thread.join()我一直在尝试使用同步方法。问题是我根本看不到任何变化,它一直给我带来与使用它们之前相同的结果。我什至不知道我到底做错了什么,同步方法假设阻止其他同步方法在完成之前执行,对吗?希望你能给我一些关于正在发生的事情的线索。
public class ThreadSync{
public static void main(String[] args) throws InterruptedException {
//if execute properly
//output can't be other than 0
while(true) {
ChangeValue counter = new ChangeValue();
Threads t = new Threads(counter,"up");
Threads t2 = new Threads(counter,"down");
Threads t3 = new Threads(counter,"print");
t.start();
t2.start();
t3.start();
}
}
}
class Threads extends Thread{
Threads(ChangeValue obj, String act){
counter = obj;
action = act;
}
@Override
public void run() {
switch(action) {
case ("up"): counter.up(); break;
case ("down"): counter.down(); …Run Code Online (Sandbox Code Playgroud) 所以,我正在使用 JavaFX 创建蛇游戏,我似乎无法让游戏正确暂停,即它偶尔会暂停,而其他时候,游戏只是忽略了暂停。所以,基本上我有一个Main类,我在其中初始化所有 GUI 组件,它还充当 javafx 应用程序的控制器。
我有一个启动/暂停游戏的Button命名gameControl,一个Boolean pause跟踪游戏状态(新/暂停/运行)的变量,以及方法startGame, pauseGame。
该gameControl按钮的EventHandler情况如下:
gameControl.setOnClicked(event->{
if(paused == null) startGame(); //new game
else if(paused) continueGame(); //for paused game
else pauseGame(); //for running game
});
Run Code Online (Sandbox Code Playgroud)
该startGame函数看起来像这样:
void startGame(){
paused = false;
Snake snake = new Snake(); //the snake sprite
//following gameLoop controls the animation of the snake
gameLoop = new AnimationTimer(){
@Override
public void handle(long now){
drawSnake(); //draws …Run Code Online (Sandbox Code Playgroud) 当应用程序通过 Java 中的 main 方法启动并为以下任务旋转其他用户线程(不是守护进程)时:
由主线程启动的用户线程将在某个时间点完成执行并终止。这将导致主线程最终终止,应用程序将停止运行。但是,正如我们看到许多曾经开始运行的应用程序一样,如果我们进行线程转储,我们可以在最底部看到主线程。这意味着主线程不会终止,这意味着启动的用户线程不会终止。
这是如何实现的?我的意思是什么是标准的编程结构和逻辑来保持线程处于活动状态而不通过无限 for 或 while 循环运行它们?
感谢您通过这个问题。每一个有用的回复都会增加我们的知识。
在早期的 Java 版本中,JVM 线程与本机操作系统线程复用。此类线程被称为“绿色线程”。这在 Java 的早期版本中已被弃用,每个 Java 线程都对应一个操作系统线程。
然而,在 Project Loom 中,执行上下文不再是线程,而是可以执行代码的“某个”对象。但它仍然必须多路复用到本机线程才能执行,不是吗?如果是这样的话,对我来说,这看起来像是回到了绿色线程。
我很确定我错过了一些我想知道它是什么的东西。我可以得到一些帮助吗?
java-threads ×10
java ×9
concurrency ×2
java-8 ×1
javafx ×1
project-loom ×1
task ×1
volatile ×1