我只是在Java中测试一些并发编程。基本上,我有一个类(Light),它是一种有限状态机,并根据命令改变其状态。这就是我正在尝试的:灯处于开启状态,我向这个类的线程发送一个命令来改变关闭状态。但是我在执行过程中遇到了一个问题。
首先,让我向大家介绍一下:
enum State {ON, OFF};
public class Light implements Runnable {
private boolean cmdOn;
private boolean cmdOff;
State state;
public Light() {
cmdOn = false;
cmdOff = false;
state = State.ON;
}
@Override
public void run() {
while(true) {
switch(state) {
case ON:
if(cmdOff) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
state = State.OFF;
}
break;
case OFF:
if(cmdOn) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
state = State.ON;
}
break;
}
}
}
public void setCmdOn(boolean cmdOn) {
this.cmdOn = cmdOn;
}
public void setCmdOff(boolean cmdOff) {
this.cmdOff = cmdOff;
}
public State getState() {
return state;
}
}
And my main class:
public class Main {
public static void main(String args[]) throws InterruptedException {
Light light = new Light();
Thread t = new Thread(light);
t.start();
printState(light, 500, 1);
light.setCmdOff(true);
printState(light, 500, 4);
}
public static void printState(Light l, int time, int number) throws InterruptedException {
for(int i= 0; i < number; i++) {
System.out.println(l.getState());
Thread.currentThread().sleep(time);
}
}
输出显示我处于ON状态,而我应该处于OFF状态。
在第二次运行时,在放入一条指令(< code>System.out.println或其他指令后...)上面的if语句验证< code>cmdOff为真,它神奇地工作了。
我不明白为什么cmdOff
变量在第一次运行期间没有传递到真!?为什么在第二次运行中它有效?我错过了一些东西,可能是一个同步块。但我找不到处理这个问题的解释。
谢谢
最好的问候,
如果没有任何同步,就不能保证正在运行的线程会看到另一个线程写入cmdOff和cmdOn的值。此外,状态上缺乏同步意味着正在运行的线程的任何更改都可能不会被另一个线程看到。尝试使cmdOn、cmdOff和state易失性。
尝试在厘米/厘米/小时关闭
上使用易失性
:
private volatile boolean cmdOn;
private volatile boolean cmdOff;
Java文档中的可变变量解释
如果没有它(或同步),更改可能不可见。
你应该了解同步。如果没有同步,您可能会遇到可见性错误,即一个线程看不到另一个线程对线程间共享的变量所做的更改。
辅导的:http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
您可以使用一个synchronized块,该块使用两个线程都知道的对象来进行锁定。如果在读取或更新共享数据时,两个线程总是在那个已知的对象上同步,那么可见性和原子性就不会成为问题。
阅读此处以完全理解“同步”:http://tutorials.jenkov.com/java-concurrency/synchronized.html您还应该能够将共享变量声明为易失性。这意味着它上的所有写入和读取都会与其他线程创建一个发生在发生之前的关系,这就是您想要的。阅读上面的教程以完全理解问题和术语。
阅读此处以充分理解“易失性”:http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html。
本文向大家介绍grep 忽略大小写,包括了grep 忽略大小写的使用技巧和注意事项,需要的朋友参考一下 示例 给定一个文件sample: grep“ hello”的法线返回: 使用-i允许忽略大小写并匹配任何“ hello”:
问题内容: 即时通讯只是从C#-> Java移动。我需要使用junit编写一些测试。在我的测试中,我需要比较两个字符串以查看它们是否匹配。因此,我们也有Assert.assertEquals,但这是区分大小写的。如何使它不区分大小写?我需要的是: 返回true。 因此,在C#中,我们曾经有: 我很快就浏览了Junit文档,但似乎找不到任何东西。 问题答案: 我发现Hamcrest提供的断言必须比默
问题内容: 是否可以确定String是否包含字符串模式?我想知道当字符不区分大小写时是否有可能。如果是这样,怎么办? 问题答案: 您可以使用 检查CharSequence是否包含搜索CharSequence(不区分大小写),处理为null。不区分大小写由String.equalsIgnoreCase(String)定义。 空的CharSequence将返回false。 这将比regex更好,因为
我有一个Spring Boot应用程序,它公开了RESTAPI。此API接受枚举列表作为查询参数。该批状态用于根据其状态过滤所有批。 当试图调用这个RESTAPI时,我得到了以下错误 Spring正在BatchStatus中寻找active,而不是active。 深入研究spring转换服务,我发现了两个转换器。StringToEnumConverterFactory(来自Spring芯) 2。S
问题内容: 这样做的目的是从用户那里获得一个句子并确定每个元音中出现了多少个。大部分是完成的,除了我不确定如何忽略大写和小写字母外,但我猜是equalsIgnoreCase或toUpperCase()。 我想也知道,如果有另一种方式做到这一点使用的一些其他类,或。我仍然是编程的新手,这一章让我丧命。 } 这里的代码 问题答案: 由于您正在比较原始字符, 应该已经是您使用Java的最佳方式。 但是,
问题内容: 我正在使用Java 7的新功能进行POC。我有在switch语句中使用String的代码,它可以工作。我也想使其不区分大小写。有没有一种方法可以在String上使用ignoreCase签出? 问题答案: 不,但是您可以打开。所以: 在我们挑剔的时候,您最好在英语语言环境中使用大写字母,以避免出现土耳其语问题