在回顾这个问题时,我注意到了这段代码:
class MyThread extends Thread {
private boolean stop = false;
public void run() {
while(!stop) {
doSomeWork();
}
}
public void setStop() {
this.stop = true;
}
}
Run Code Online (Sandbox Code Playgroud)
但是我不明白为什么会失败.其他线程是否无法访问"实际"停止变量?
根据javadoc通知唤醒正在此对象监视器上等待的单个线程.如果任何线程正在等待此对象,则选择其中一个线程被唤醒.选择是任意的,由实施决定.线程通过调用其中一个wait方法等待对象的监视器.
我想知道notify如何实现这种行为.在我读过的很多网站上发送信号但信号在这里意味着什么?
notify是否直接向第一个等待线程发送信号,或者它向线程调度程序发送信号?
我从原子学教程中获取了这段代码,它说:
"通过使用AtomicInteger作为Integer的替代,我们能够在线程安全的庄园中同时增加数量,而无需同步对变量的访问.方法incrementAndGet()是一个原子操作,所以我们可以安全地从多个调用此方法线程".
它说这将返回正确的结果,但是实例都没有达到1000,它们通常相当少,例如
test1 result = 532
test2 result = 128
Run Code Online (Sandbox Code Playgroud)
怎么了 ?
public class AtomicsTest {
public static void main(String... args){
AtomicsTest test = new AtomicsTest();
test.test1();
test.test2();
}
public void test1() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newSingleThreadExecutor();
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
System.out.println("test1 result = "+ atomicInt.get());
executor.shutdown();
}
public void test2() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newFixedThreadPool(2);
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
System.out.println("test2 result = " + atomicInt.get());
executor.shutdown();
}
}
Run Code Online (Sandbox Code Playgroud) Threadclass 有许多按类名调用的静态方法。他们之中有一些是:

但是,我们提供了currentThread()返回当前正在执行的线程对象的方法。一些是:

不幸的是,这在我的脑海中造成了混乱。当我想到我想要的方法时,我不知道我会发现它是static还是instance。那么他们为什么要采用这两种方法呢?
我的意思是,他们不能都归为同一个“呼叫”吗?例如,为什么使用sleep() 静态而不是实例方法调用Thread.currentThread().sleep()?另一个奇怪的例子是在不同的方式之间interrupted()和isInterrupted()定义的。他们做完全一样的事情,只是interrupted()另外清除了中断标志。有没有人对此有逻辑回答,所以我毫不费力地在哪里找到每种方法?
我正在研究在一个简单的HelloWorldjava 程序上进行了哪些系统调用。通过一个简单的strace我注意到没有write电话,我发现这是可疑的:
...
mprotect(0x7f0bcd852000, 4096, PROT_READ) = 0
mprotect(0x7f0bce915000, 790528, PROT_READ) = 0
getpid() = 27931
munmap(0x7f0bcf6ac000, 174284) = 0
getpid() = 27931
mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f0bcf5d6000
clone(child_stack=0x7f0bcf6d5fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f0bcf6d69d0, tls=0x7f0bcf6d6700, child_tidptr=0x7f0bcf6d69d0) = 27932
futex(0x7f0bcf6d69d0, FUTEX_WAIT, 27932, NULLHello, World
) = 0
munmap(0x7f0bbfa6c000, 140063364) = 0
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
Run Code Online (Sandbox Code Playgroud)
因此,正如您在上面看到的,在正常strace调用中,只会进行一次futex调用,该调用正在等待字符串地址。
因此,我strace使用-f参数运行以查看所有线程:
[pid 28249] pread64(3, …Run Code Online (Sandbox Code Playgroud) 我有一个主班
public class Main{
public static void main(String[] args) {
Gui gui = new Gui();
}
}
Run Code Online (Sandbox Code Playgroud)
那我再上课Gui
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
public class Gui extends Application{
public Gui() {
Application.launch();
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("");
FlowPane flowLayout= new FlowPane();
Scene scene = new Scene(flowLayout,200,200);
primaryStage.setScene(scene);
primaryStage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
我也想通过创建Gui实例并使用默认构造函数从Main类启动Javafx Application。我该怎么做?
我有变量,我想在线程之间共享,但他们给我一些问题!我有一个Integer,我希望主程序与它正在创建的线程共享,并允许线程更改其值并被其他线程和主程序看到(我有两种不同类型的线程,我想创建不止一个).我已经考虑了关键部分.这是我的计划的一部分:
public static void main(String[] args) throws InterruptedException{
Integer t = 0; //What do I change here?
(new Te(t)).start();
(new In(t)).start();
}
Run Code Online (Sandbox Code Playgroud)
我没有编写我的所有程序,但在这种情况下,感兴趣的变量是t,它将由Threads更改,并且主要程序必须看到它的新的有价值,以防它创建新的线程和线程时它们想要读/写.
如果不清楚这些,我可以发布更多的代码,如果需要的话!
非常感谢你提前:)
刚开始使用 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
就像标题一样,给定 2 个数组int[] a,由两个线程共享,每个线程以第一个数组的每个元素都是第二个数组的对应元素int[] b的方式重新排列两个数组的元素,输出似乎总是正确的,而不需要同步需求<=a[i] <= b[i]
public class MyClass {
int[] a = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
class MyThread extends Thread {
public void run() {
for (int i = 0; i < a.length; i++) {
if (a[i] > b[i]) {
int temp = b[i];
b[i] = a[i];
a[i] = …Run Code Online (Sandbox Code Playgroud) java multithreading synchronization thread-safety java-threads
那些开发过专业的多线程 Java Spring 应用程序的人可能可以证明 volatile 关键字的使用几乎不存在(以及与此相关的其他线程控制),尽管在需要时错过它可能会带来灾难性的后果。
让我提供一个非常常见的代码示例
@Service
public class FeatureFlagHolder {
private boolean featureFlagActivated = false;
public void activateFeatureFlag() {
featureFlagActivated = true;
}
// similar code to de-activate
public boolean isFeatureFlagActivated() {
return featureFlagActivated;
}
}
Run Code Online (Sandbox Code Playgroud)
假设改变和读取状态的线程featureFlagActivated不同。AFAIK,读取布尔值的线程可以根据 JVM 缓存其值并且从不刷新它。在实践中,我从未见过这种情况发生。事实上,我什至从未见过布尔值在读取时没有立即更新。
这是为什么?