We are using the ScheduledExecutorService.scheduleAtFixedRate to perform an I/O Task every 100ms. (The actual I/O Operation is performed by a third party library and we don't know exactly what is happening inside.)
Sometimes keeping up with the 100ms intervals has some issues and we fall back to 500ms. Since it is I/O, we weren't surprised, but we observed a strange behaviour:
If a specific Thread runs, we are matching the 100ms. If this Thread is not running, we are falling …
我thread.isInterrupted对下面程序中的行为感到有点困惑.
public class ThreadPractice {
public static void main(String args[]) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("Starting thread..." + Thread.currentThread().getName());
Thread.sleep(10000);
System.out.println("Waking up");
}catch(InterruptedException e){
System.out.println("Thread is interrupted!!!");
Thread.currentThread().interrupt();
}
}
});
t.start();
Thread.sleep(2000);
t.interrupt();
//System.out.println(!t.isInterrupted());
while(!t.isInterrupted()){
System.out.println("Current thread not interrupted!!!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
当执行上述程序时,它打印,
Starting thread...Thread-0
Thread is interrupted!!!
Run Code Online (Sandbox Code Playgroud)
但是当我取消注释System.out语句以打印中断状态时,它会遇到无限循环打印"当前线程未被中断"
我无法弄清楚System.out语句的确切区别.
线程1:正在执行此循环
while(running) {
// Do Task()
}
println("Done");
Run Code Online (Sandbox Code Playgroud)
线程2设置运行false如果运行是一个volatile变量,则thread1退出循环并打印"Done".
我的问题是,如果运行不是易失性的,那么Thread1何时从主内存中读取运行变量?
注意:我知道在关于同步和volatile变量的关系之前发生了,但是即使运行不是volatile或synchronized,线程1也会停止.所以我的问题是线程1何时决定从主存储器中读取,因为没有同步或没有挥发性
我试图创建一些场景来演示跨线程共享变量时的可见性问题.我注意到在我测试的几乎所有情况下,如果在run()内部,我在使用共享变量的同一代码块中添加了System.out.println()语句,则无法生成可见性问题.我将举一个例子:
配置详细信息 - Oracle Java6 64位,Eclipse Juno SR 2
1)有可见性问题:
public class NoVisibility_Demonstration extends Thread {
boolean keepRunning = true;
public static void main(String[] args) throws InterruptedException {
NoVisibility_Demonstration t = new NoVisibility_Demonstration();
t.start();
Thread.sleep(1000);
t.keepRunning = false;
System.out.println("keepRunning is false");
}
public void run() {
int x = 1;
while (keepRunning)
{
//System.out.println("If you uncomment this line, the code will work without the visibility issue");
x++;
}
System.out.println("x:"+x);
}
Run Code Online (Sandbox Code Playgroud)
}
输出:线程保持无限运行
上面的相同代码,带有未完成的println()运行中的语句()
OUTPUT:
...
如果取消注释此行,代码将在没有可见性问题的情况下工作
如果取消注释此行,代码将在没有可见性问题的情况下工作
如果取消注释此行,代码将在没有可见性问题的情况下工作 …
我之前回答了一个关于线程安全的问题,但我没有得到明确的答案(我认为).
因此,我一直试图通过让成千上万的线程读写该对象来说服自己设计被破坏(可见性) - 但我无法得到任何意外的结果.这显然不是证明它是线程安全的证据,可能只是我自己限制的证明!
我理解重新排序的风险,但我不知道它在这种情况下是如何应用的,因为方法中的clone实例bar()是本地的,并且其字段的更改在释放到外部世界之前完成return,之后实例实际上是不可变的.因此,查看返回对象的线程会看到它的bar字段已经设置为正确的值...
所以我的问题是: 什么样的代码可以显示一段使用的代码,IsItSafe并且可以导致2个线程看到bar给定实例的字段的不同值IsItSafe?
为了参考和便于阅读,我在这里复制代码:
public class IsItSafe implements Cloneable {
private int foo;
private int bar;
public IsItSafe foo(int foo) {
IsItSafe clone = clone();
clone.foo = foo;
return clone;
}
public IsItSafe bar(int bar) {
IsItSafe clone = clone();
clone.bar = bar;
return clone;
}
public int getFoo() {
return foo;
}
public int getBar() {
return bar; …Run Code Online (Sandbox Code Playgroud) 我需要一个volatile在java 中使用关键字的简单示例,由于不使用而表现不一致volatile.
挥发性使用的理论部分对我来说已经很清楚了.
如果我有一个只有一个这样的语句的getter方法
public class NumberClass{
int number;
public int getNumber() {
return number;
}
...
}
Run Code Online (Sandbox Code Playgroud)
多线程访问此方法,我是否必须同步此方法或没有必要,因为它只有一个语句?
我刚刚在这里读了一个问题,并且阅读了@JB Nizet最评价的答案,我感到困惑......根据答案,在下面的代码中,
private int a=0;
public void foo(){
int temp=35;
a=28;
a=temp;
}
Run Code Online (Sandbox Code Playgroud)
a=28; 是原子操作.
在我在#1读过一些其他的问题和答案,信息是不同的,说a=28;是不是一个原子操作,因为第一右操作数的读操作时发生,则写操作发生,并且每个这两个操作是原子的,但整个任务不是(说实话,这就是我认为它的工作方式).
那怎么样a=temp;?它a=28;与原子性有什么不同?
顺便说一下,我知道volatile和double需要对它们进行原子读/写操作,只是对我上面写的内容感到困惑.
有人可以详细说明吗?
谢谢..
我知道为了使程序成为线程安全的,建议使用synchronized方法或代码块.疑问是下面的代码片段将如何使程序线程安全?幕后发生了什么?
public class MyCounter
{
private int count = 0; // count starts at zero
public synchronized void setCount(int amount)
{
count = amount;
}
public synchronized int getCount()
{
return count;
}
}
Run Code Online (Sandbox Code Playgroud)