Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的多线程无法传递更改_Java_Multithreading - Fatal编程技术网

java中的多线程无法传递更改

java中的多线程无法传递更改,java,multithreading,Java,Multithreading,我必须在应用程序线程(setReadyToUpload)中更改一个布尔变量,听到这个更改(isReadyToUpload),另一个线程(服务器线程)将做一些事情。虽然服务器线程处于while循环中,并且一直在检查,但当我在应用程序线程中更改布尔变量时,它没有捕获到更改。 应用程序线程 package server; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Aler

我必须在应用程序线程(setReadyToUpload)中更改一个布尔变量,听到这个更改(isReadyToUpload),另一个线程(服务器线程)将做一些事情。虽然服务器线程处于while循环中,并且一直在检查,但当我在应用程序线程中更改布尔变量时,它没有捕获到更改。 应用程序线程

package server;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.stage.FileChooser;

import java.io.File;

public class serverController {
serverMain main;

@FXML
private Button upload;

@FXML
private ProgressIndicator indicator;

@FXML
void pressed(ActionEvent event) {
    FileChooser fc=new FileChooser();

    File file=fc.showOpenDialog(main.getStage());


    if(file!=null) {
        main.setFileLoaction(file.getAbsolutePath());
        System.out.println("it is done");
        main.setReadyToUpload(true);

    }
    else
    {
        Alert alert=new Alert(Alert.AlertType.ERROR);
        alert.setHeaderText("Upload problem");
        alert.setContentText("You have'nt select any file to upload");
        alert.showAndWait();

    }


}
public void setMain(serverMain main) {
    this.main = main;
}
}

服务器线程

package tcpobject;


import java.io.File;
import java.util.*;

import server.serverMain;
import util.NetworkUtil;

public class WriteThreadServer implements Runnable {

private Thread thr;
private NetworkUtil nc;
private  serverMain main;
private LargeFile o;
private  LargeFileInserter lfi;
String name;

public WriteThreadServer(NetworkUtil nc,String name, serverMain main) {
    this.nc = nc;
    this.name=name;
    this.thr = new Thread(this);
    this.main=main;
    thr.start();
}

public void run() {
    while(true)
    {
        try {
            //System.out.println("it is "+main.isReadyToUpload());
            // if i print this then thelower block works good but if i dont it cant catch the change
            System.out.println("it is checking");
            if(main.isReadyToUpload())
            {
                System.out.println("it is ru");
                FileDataHandler();
            }

            if(main.isStartUpload()) {
                //System.out.println("it is su");
                LargeFileHandler();
                System.out.println("it is su");
                for (int i = 0; lfi.hasMoreBytes(); i++) {
                    o = lfi.nextByte();
                    nc.write(o);
                }
                lfi.close();

            }

        } catch(Exception e) {
            System.out.println (e+"  here");
            e.printStackTrace();
            nc.closeConnection();
        }

    }

}
void FileDataHandler ()
{

    FileDataMessage fd=new FileDataMessage(main.getFileLoaction());
    nc.write(fd);
    main.setReadyToUpload(false);

}
void LargeFileHandler ()
{

    try {
        lfi=new LargeFileInserter(main.getFileLoaction());
    } catch (Exception e) {
        e.printStackTrace();
    }
    //FileDataMessage fd=new FileDataMessage("F:\\L-2 T-1\\EEE 263\\Electronic devices and ckt theory- boylestad 11th edition.pdf");
    //System.out.println(fd);
    //System.out.println(fd.sizetoPrint());
    LargeFile o;
    main.setStartUpload(false);
}
}


所有函数和变量都写在主类中,两个线程都可以访问该类。

如果没有剩余的代码可用,则方法
setReadyToUpload
isReadyToUpload
在共享对象的可见性方面存在问题,这是您设置为true的标志

可能发生的情况是,两个线程在不同的内核上运行,一个线程将标志更新为true。此更新可能发生在CPU缓存内,而另一个线程在检查值时无法读取该缓存,只要更改未刷新回主内存

您可以通过以下方式修复当前设计:

a) 具有将强制更新CPU寄存器之间缓存线的volatile标志

b) 使方法同步,效果同上

然而,您应该做的是使用wait和notify,而不是在服务器线程中忙着等待并浪费CPU周期

只需创建
monitor
变量,例如:

private final Object monitor = new Object();
在服务器代码中执行以下操作:

synchronized(monitor) {

    monitor.wait():
}
因此,当更改准备就绪时,您可以从另一个线程通知更改,如下所示:

synchronized(monitor)

{
   monitor.notify();
}
当您的客户机是
主题时,服务器可以实现
Observer
。这将使您只需通过观察者的界面方法
update
通知更改


请注意,从理论上讲,
等待
可能会被中断,因此您应该在醒来时检查是否满足条件,如果不继续等待。

请您具体说明您的问题?请提供更多的代码,让您的
标志
不稳定。setReadyToUpload和isReadyToUpload是否同步?您应该为这两种方法提供代码。1)永远不要忙着等待。2) 永远不要忙着等待。3) 对于由两个线程读取的变量,它需要有一个内存屏障-
volatile
在这种情况下可以工作。我必须检查服务器线程中的许多变量,以便可以等待单个变量吗?(添加了代码)查看观察者模式。我认为这将帮助您更好地理解这个问题,下面是一个简单的实现:。您应该等待事件,而不是变量。在您的例子中,事件是将标志更新为true,这可以转化为观察者的更新。@enigma您的代码举例说明了编写糟糕的多线程代码的所有错误。在许多核心CPU的时代,阻塞整个CPU来测试某些变量已不像过去那样是一种容易引起火灾的罪行;但是如果我在我的代码库中看到这一点,就会使用
git-bull
,并使用强有力的词语。考虑学习关于事件驱动的编程,或者至少,<代码>等待< /代码>和<代码>通知< /代码>,