while((c=(char)in.read())!=-1)
这句的条件错误
虽然文档上说流结束时返回-1,也许是文档没有更新,当事实上当所有数据都读完时in.read()将阻塞!除非调用in.close()否则while将无法停止。
这句的条件错误
虽然文档上说流结束时返回-1,也许是文档没有更新,当事实上当所有数据都读完时in.read()将阻塞!除非调用in.close()否则while将无法停止。
调试欢乐多
String m="";
while((c=(char)in.read())!=-1){
m=m+c;
System.out.print(m);
}
System.out.print(m);每一次都可以打印出m的值,我每次从thread1线程的out写一个String,thread2的m就会打印到该String的值,只不过不能跳到循环外打印m。如果真的是int read()读完数据后不能返回-1,我的程序应该如何解决?
Thread1:
PipedWriter out=new PipedWriter();
String m="abcd";
out.write(m.toCharArray());
out.close(); //加入close() 就可以了Thread2:
PipedReader in=new PipedReader(out);
char c;
while((c=(char)in.read())!=-1){
m=m+c;
System.out.print(m);
}
System.out.print(m);//这句死活都不执行,这是为什么原因?==>因为out并没有close(),读不到-1 ,so wait until at least one byte of input is available.另外主线程要注意,两个线程都start后,main有可能很快就中止了,并不能保证thead2能把所有的thread1输出的字符全部读出,所以如果要看效果的话,可以再main中加入thread2.join(),让主线程等待thread2把流中的字符全部读出,然后再中止。
当然,join方法已经不推荐使用了,此处仅为测试,如果要写健壮的代码,可以考虑其他比较优化的结构。
extends Thread
{
public Demo()
{ } public static void main(String[] args) throws Exception
{
Demo demo = new Demo();
demo.start();
int count = 0;
while(true)
{
if(demo.mNotify.available()==0)
{
//键盘没有输入,作些其它事情...
Thread.sleep(500);
if(++count > 20)
{
System.out.println("你个大菠萝,我砍翻你!");
count=0;
}
}
else
{
demo.mNotify.read();
if (demo.mCommand.compareTo("QUIT") == 0 ||
demo.mCommand.compareTo("quit") == 0)
{
System.out.println("回家睡觉");
return;
} System.out.println("没事别烦我,忙着呢...");
}
}
} String mCommand;
final PipedInputStream mNotify=new PipedInputStream();
public void run()
{
try
{
BufferedReader read = new BufferedReader(new InputStreamReader(
System.in));
PipedOutputStream notify=new PipedOutputStream(mNotify);
while (true)
{
mCommand = read.readLine();
notify.write(0);
notify.flush();
if (mCommand.compareTo("QUIT") == 0 ||
mCommand.compareTo("quit") == 0)
{
notify.close();
break;
}
}
}
catch (Exception e)
{
}
}}
用一个线程(生产者)在一个死循环当中不断读取输入.当读到输入则唤醒消费者,因为IO方法自动阻塞,所以不必令其睡觉.(不消耗系统资源)
另一个线程(消费者)在一个死循环当中不断输出结果.如果没有数据则阻塞,被唤醒之后处理数据,然后阻塞(循环当中)这两个死循环都依赖一个变量 :
boolean stop = false;while (!stop) {
....
}当程序要退出的时候,主线程设置 stop = true, 之后两个线程安全退出.代码太罗嗦,就不贴了.
你所描述的这种情况,只有一个消费者,一个生产者,并且消费者在生产者阻塞时也跟着阻塞,放两个线程大部分时间在那阻塞这有必要吗?键盘是低速设备,还不如就一个主线程直接接收键盘输入,得到后自己处理效果是一样的。现在楼主的需求是:有两个(或更多)的生产者的数据需要处理,一个是键盘输入的<命令>另一个是与<命令>在逻辑上紧密相关的<数据>。
在键盘输入阻塞时需要处理<数据>,因此需要一个独立的线程监控键盘输入,另一个线程处理<数据>,因为<命令>与<数据>在逻辑顺序上紧密相关用第三个线程处理将会使问题复杂化,因此处理数据的线程不想阻塞并不时的回来看看键盘是否输入了命令以决定下一步处理。举一个实际的例子:简单的交换机终端,接收用户输入的命令,(处理后或直接)发给交换机,然后接收交换机报告,程序在接收交换机的报告时必须同时监控用户输入的命令,但是否处理命令如何处理要看交换机的应答报告,成功、失败、等待输入参数等,因为这个交换机是半双工的因此必须确认交换机不在吐数据时才能发命令否则将造成一次交互失败。