Java 线程始终在运行,可以';停不下来
我想做一个测试,两个线程,一个线程正在更改值,另一个线程等待第一个线程,然后中断并完成。但问题是等待的线程总是在运行,不能再停止。另一个问题是,当我打开“System.out.println(i+“run”);”的代码时,所有线程都可以正常工作,这太奇怪了Java 线程始终在运行,可以';停不下来,java,Java,我想做一个测试,两个线程,一个线程正在更改值,另一个线程等待第一个线程,然后中断并完成。但问题是等待的线程总是在运行,不能再停止。另一个问题是,当我打开“System.out.println(i+“run”);”的代码时,所有线程都可以正常工作,这太奇怪了 import java.util.Date; public class ThreadTestTwo { public int a = 0, b = 0,c = 0; public static void main(String[]
import java.util.Date;
public class ThreadTestTwo {
public int a = 0, b = 0,c = 0;
public static void main(String[] args) {
System.out.println(new Date()+"start");
for (int i = 0; i < 100000; i++) {
new ThreadTestTwo().start(i);
if(i % 100000 == 0){
System.out.println(i/100000);
}
}
System.out.println(new Date()+"finish");
}
public void start(final int i){
Thread readThread = new Thread(){
@Override
public void run() {
while (true) {
if(c == 1){
b = a;
// System.out.println(i+", set b "+a);
break;
}
// System.out.println(i + " run");
}
}
};
Thread writeThread = new Thread(){
@Override
public void run() {
a = 1;
c = 1;
}
};
writeThread.setName("mywrite");
readThread.setName("myread");
System.out.println(i+" start");
writeThread.start();
readThread.start();
try {
writeThread.join();
readThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i+" end");
if(b != 1)
throw new RuntimeException("b = "+b);
}
}
import java.util.Date;
公共类ThreadTest2{
公共整数a=0,b=0,c=0;
公共静态void main(字符串[]args){
System.out.println(新日期()+“开始”);
对于(int i=0;i<100000;i++){
新的ThreadTestTwo().start(i);
如果(i%100000==0){
系统输出打印项次(i/100000);
}
}
System.out.println(新日期()+“完成”);
}
公共作废开始(最终int i){
线程readThread=新线程(){
@凌驾
公开募捐{
while(true){
如果(c==1){
b=a;
//系统输出打印项次(i+),设置b“+a);
打破
}
//System.out.println(i+“run”);
}
}
};
线程writeThread=新线程(){
@凌驾
公开募捐{
a=1;
c=1;
}
};
writeThread.setName(“mywrite”);
setName(“myread”);
System.out.println(i+“开始”);
writeThread.start();
readThread.start();
试一试{
writeThread.join();
readThread.join();
}捕捉(中断异常e){
e、 printStackTrace();
}
系统输出打印项次(i+“结束”);
如果(b!=1)
抛出新的运行时异常(“b=“+b”);
}
}
在线程之间使用简单的int作为信号不是一个好主意,因为它不是线程安全的
因此,请尝试改用AtomicInteger,或者将int设置为volatile,看看会发生什么情况。除非变量标记为volatile,或者需要使用同步或显式锁定来处理事务,否则不能保证在另一个线程中看到一个线程的写入操作。 在您的例子中,a、b、c是多个线程访问的实例变量,读线程缓存这些值,因此它看不到写入线程的刷新值 有关更多详细信息,请参阅以下链接:
我建议您阅读更多关于线程的内容。这是一份来自O'Realy的有趣文件: 至于您的实现,您应该知道线程对一个变量的修改可能不会被读线程看到。要解决此问题,请使用
synchronized
获取和设置,访问同步块中的变量,或使用AtomicReference
。您还可以使用锁
,例如ReantrantLock
另外,如果您有两个线程,其中第一个线程正在等待第二个线程的输入,那么您可以在synchronized
块中为第一个线程使用wait()
,以便第二个线程在完成其工作时可以notify()
第一个线程
大概是这样的:
import java.util.Date;
公共类ThreadTest2{
私有整数a=0,b=0,c=0;
私有最终对象锁=新对象();
//任何物体都像锁一样好,对于这样一个简单的例子来说都可以。
//此对象将用作同步块的监视器。
公共作废开始(最终int i){
线程readThread=新线程(){
@凌驾
公开募捐{
已同步(锁定){
试一试{
而(c!=1){
lock.wait();
}
}
捕获(中断异常例外){
//异常处理
}
b=a;
}
//System.out.println(i+“run”);
}
};
线程writeThread=新线程(){
@凌驾
公开募捐{
已同步(锁定){
a=1;
c=1;
lock.notify();
}
}
};
writeThread.setName(“mywrite”);
setName(“myread”);
System.out.println(i+“开始”);
writeThread.start();
readThread.start();
系统输出打印项次(i+“结束”);
}
公共静态void main(字符串[]args){
System.out.println(新日期()+“开始”);
对于(int i=0;i<100000;i++){
新的ThreadTestTwo().start(i);
如果(i%100000==0){
系统输出打印项次(i/100000);
}
}
System.out.println(新日期()+“完成”);
}
}
我想说你不需要用这个方法join()
。但是如果要在第一个线程完成后等待第二个线程启动,则必须在启动它之前使用join()
。像这样:
writeThread.start();
试一试{
writeThread.join();
}
捕获(中断异常例外){
//异常处理
}
readThread.start();
试一试{
readThread.join();
}
捕获(中断异常例外){
//异常处理
}
但是如果您在这个特殊情况下使用join()
,,我会说您不需要任何同步的块或条件,因为第二个线程只会在第一个线程死后启动。大概是这样的:
公共作废开始(最终int i){
线程readThread=新线程(){
@凌驾
公开募捐{
b=a;
//System.out.println(i+“run”);
}
};
线程writeThread=新线程(){
@凌驾
公开募捐{
a=1;
c=1;
}
};
setName(“mywrite