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
Java 在线程的run()中条件检查失败_Java_Multithreading_If Statement - Fatal编程技术网

Java 在线程的run()中条件检查失败

Java 在线程的run()中条件检查失败,java,multithreading,if-statement,Java,Multithreading,If Statement,run()方法中的计数检查无效。知道为什么吗?我可以看到,每次调用计数都会增加,但检查不起作用,每次控件传递到read()方法,而不是write()时 我做错了什么?另外,根据具体情况,是否有其他有效的方法从两个线程调用多个方法 另外,我正在尝试使用一个线程读取输入,并将输入值写入另一个线程中的文件不要为每一行创建新的BufferedReader。在插座的使用寿命内使用相同的插座。每个BufferedReader读取的数据都将丢失。请删除除主方法外的所有静态数据。。。您需要确保的是读和写不会同时

run()方法中的计数检查无效。知道为什么吗?我可以看到,每次调用计数都会增加,但检查不起作用,每次控件传递到read()方法,而不是write()时

我做错了什么?另外,根据具体情况,是否有其他有效的方法从两个线程调用多个方法


另外,我正在尝试使用一个线程读取输入,并将输入值写入另一个线程中的文件

不要为每一行创建新的
BufferedReader
。在插座的使用寿命内使用相同的插座。每个
BufferedReader

读取的数据都将丢失。请删除除主方法外的所有静态数据。。。您需要确保的是读和写不会同时更改/读取“计数”。。。使用不同的锁对象,如“lockObject”,并使用wait()和notify()。你在这里寻找一种生产者/消费者模式。下面是一个例子:

试试这个:

public class MultiThreadExample extends Thread {
    public static int count=0;
    static String s="";
    synchronized public static String read(){
        String line="";
        System.out.println("Enter new line:");
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        try {
            line=br.readLine();
            count++;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return line;

    }

    synchronized public static void write(String line){
        try {
            BufferedWriter br=new BufferedWriter(new FileWriter("C://name.txt"));
            br.write(line);
            System.out.println(line);
            br.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

    public void run(){
        if(count==0){
            System.out.println("Read " + s + " Count " + count);
            s=read();
            System.out.println("Read " + s + " Count " + count);
        }
        else{
            write(s);
            System.out.println("Write" + s + " Count " + count);
        }
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MultiThreadExample th1=new MultiThreadExample();
        MultiThreadExample th2=new MultiThreadExample();
        th1.start();
        th2.start();
    }

}

count
标记为volatile。这确保了其他线程可以看到来自一个线程的更改。只要只有一个线程更新
count
,这就可以了,否则,您可以将
AtomicInteger
、AtomicIntegerFieldDupDater与易失性字段结合使用,或者(如果您测量到高争用,在您的情况下不太可能)使用
LongAdder
(所有类都来自
java.util.concurrent.atomic
包,最后一个仅在java 8中可用)。

也可以尝试“类似”的方法,任何线程都先进入读取,而后者等待前者读取,然后再写入。(不需要同步静态方法)


好的,你能给我解释一下,为什么我以前的代码不起作用,而检查失败了

@Shail016在对你的问题的评论中解释了这一点。下面是一个可能的事件序列

主线程调用
th1.start()
,调用
th2.start()
,然后退出

线程1进入
run()
方法,看到count==0,进入
read()
方法,调用
System.out.println(…)

线程2进入
run()
方法,看到count==0,尝试进入
read()
方法,被阻塞,等待互斥锁

线程1从
System.out.println(…)
调用返回,读取一行,增加
计数,然后返回

允许线程2进入
读取()
,等等

等等


等。

好的,但这是另一个问题,if(count==0)条件检查失败。知道原因吗?解决后,我将更改BufferedReader行尝试如下声明计数:public volatile static int count=0;不,它仍然不起作用..:(@Win.ubuntu-这根本不是必需的。同步块/方法确保在存在之前发生。即使您添加
volatile
,JIT也很可能只是为您删除/忽略它。因为您的条件(即计数读取)不是线程安全的,线程可以在以下情况下执行(计数==0),读取相同的值0,然后等待阻止读线调用。如果您的目的是让一个线程读取,另一个线程写入,则需要一个信号机制,如Object.wait and notify……或者您需要足够快,以便在第二个线程检查条件之前向第一个线程提供输入。:)你好,@Shail016,你能发布你刚刚给出并删除的答案吗?想看看你在那里做了什么。:)仍然不起作用。。结果相同,只是因为睡眠的原因有延迟()好的,你能给我解释一下,为什么我以前的代码不起作用,而检查失败了吗?@Shubharti Dasgupta这里有两个线程顺序运行,即th2.run在th1之后执行。run finishesMark count为volatile。这不是必需的。同步可以确保在之前发生。而且,这还不够。问题是访问
count
未同步假定“读取器”角色的线程在递增计数之前将执行多个I/O操作。这使另一个线程有足够的机会在递增发生之前测试计数(对计数的访问在测试点不同步)。因此,两个线程都很可能假定为“读取器”角色
    MultiThreadExample th1=new MultiThreadExample();
    MultiThreadExample th2=new MultiThreadExample();
    th1.start();
   try {
    th1.join();
} catch (InterruptedException ex) {
    System.out.println(ex.getMessage());
}
    th2.start();
static ReentrantLock l = new ReentrantLock();
        public void run(){
            l.lock();
            if(count==0){
                System.out.println("Read " + s + " Count " + count);
             s=read();
            l.unlock();              
            System.out.println("Read " + s + " Count " + count);
            }
            else{
                write(s);
                System.out.println("Write" + s + " Count " + count);
            }           
        }