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();
}
}
run()方法中的计数检查不起作用。知道为什么吗?我可以看到,每次调用都会增加计数,但是检查不起作用,每次控件传递给read()方法,并且不会去写()
我做错了什么?另外,还有其他有效的方法从两个线程调用多个方法,具体取决于具体情况吗?
P.S。我试图使用一个线程读取输入,并将输入值写入另一个线程中的文件
答案 0 :(得分:1)
不要为每一行创建新的BufferedReader
。在插座的使用寿命中使用相同的一个。您正在丢失每个BufferedReader
预读的数据。
答案 1 :(得分:1)
删除除主要方法之外的所有静态...所有你需要确保的是读写不要改变/读取"计数"同时...使用不同的锁定对象,如" lockObject"并使用wait()和notify()。您正在寻找生产者/消费者类型的模式。以下是一个示例:http://www.programcreek.com/2009/02/notify-and-wait-example/
答案 2 :(得分:1)
试试这个:
MultiThreadExample th1=new MultiThreadExample();
MultiThreadExample th2=new MultiThreadExample();
th1.start();
try {
th1.join();
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
th2.start();
答案 3 :(得分:1)
也可以尝试类似的'做法。 ,哪个线程进入第一次读取,后一个等待前者读取然后写入。 (它不需要你的静态方法同步)
Use following code it might be work because in my case it's working.
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModel.cs,
public ICommand WindowLoadedCommand
{
get { return new RelayCommand<object>(WindowLoadedCommandExecute); }
}
public void WindowLoadedCommandExecute(object obj)
{
}
答案 4 :(得分:1)
好的,你可以向我解释一下,为什么我之前的代码无效,检查失败了吗?
@ Shail016在对你的问题的评论中解释了这一点。这是一个可能的事件序列。
主线程调用th1.start()
,调用th2.start()
,然后退出。
主题1进入run()
方法,看到计数== 0,输入read()
方法,调用System.out.println(...)
线程2进入run()
方法,看到count == 0,尝试输入read()
方法,被阻止,等待互斥锁。
线程1从System.out.println(...)
调用返回,读取一行,递增count
,然后返回,
允许线程2进入read()
等等,
等
等
答案 5 :(得分:0)
将count
标记为易变。这可确保其他线程可以看到来自一个线程的更改。只要只有一个主题更新count
,就可以了,否则,您可以使用AtomicInteger
,AtomicIntegerFieldUpdater
和volatile字段,或者(如果您测量高争用,在您的情况下不太可能)LongAdder
(所有类都来自java.util.concurrent.atomic
包,最后一个只在Java 8中可用。)