十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
线程启动要调start方法, 你调run方法相当于只有一个主线程, 因此输出一部分数据后线程就被就阻塞了, 所以只要将
主要从事网页设计、PC网站建设(电脑版网站建设)、wap网站建设(手机版网站建设)、成都响应式网站建设公司、程序开发、微网站、重庆小程序开发公司等,凭借多年来在互联网的打拼,我们在互联网网站建设行业积累了丰富的成都网站设计、成都网站建设、网络营销经验,集策划、开发、设计、营销、管理等多方位专业化运作于一体,具备承接不同规模与类型的建设项目的能力。
new Thread(ts).run();
new Thread(tr).run();
改成
new Thread(ts).start();
new Thread(tr).start();
就行了
在Java的IO流中有一种很非凡的流就是管道流类:PipedInputStream PipedOutputStream.这两个类的实例对象必须要通过connect方法连接.
其实看这么一个程序就知道了管道流类的使用方法.
//sender.java
import java.io.*;
import java.util.*;
public class sender extends Thread
{
PipedOutputStream out = new PipedOutputStream();
public PipedOutputStream getOut()
{
return out;
}
public void run()
{
String str = "Hello,receiver ! I`m sender\n";
try
{
out.write(str.getBytes());
out.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
//receiver.java
import java.io.*;
import java.util.*;
public class receiver extends Thread
{
PipedInputStream in = new PipedInputStream();
public PipedInputStream getIn()
{
return in;
}
public void run()
{
byte [] buf = new byte[1024];
try
{
int len = in.read(buf);
System.out.println("the following is from sender:\n"+new String(buf,0,len));
in.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
//TestPiped.java
import java.io.*;
class TestPiped
{
public static void main(String [] args)
{
sender s = new sender();
receiver r = new receiver();
PipedOutputStream out = s.getOut();
PipedInputStream in = r.getIn();
try
{
in.connect(out);
s.start();
r.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
这个程序的功能是sender发送”Hello,receiver ! I`m sender”给receiver然后receiver接受后显示出来并且在前面加上”the following is from sender”的信息.要注重的就是PipedInputStream和PipedOutputStream分别用两个线程传送数据.
import java.awt.*; //awt的图形包
import javax.swing.*;//swing的图形包
import java.io.*; //IO流处理包
import java.awt.event.*; //事件处理包
public class CDInfor extends JFrame implements ActionListener//继承swing 的Frame 实现 事件接口
{
BufferedReader in; //输入输出管道流
FileWriter out;
JPanel jPanel1 = new JPanel(); //定义 6个Jpanel(容器)用来装组件 (就是你按钮什么的)
JPanel jPanel2 = new JPanel(new GridLayout(4,1)); //其中这个是 用网格的布局管理器
JPanel jPanel3 = new JPanel();
JPanel jPanel5 = new JPanel();
JPanel jPanel4 = new JPanel();
JPanel jPanel6 = new JPanel();
JScrollPane jScrollPane1 = new JScrollPane(); //定义滚动条
JTextArea jTextArea1 = new JTextArea("",10,25); //定义输入框
GridLayout gridLayout1 = new GridLayout(); //整体用的事 网格布局管理器
JTextField jTextField1 = new JTextField(10); //文本输入框
JTextField jTextField2 = new JTextField(10);
JTextField jTextField3 = new JTextField(10);
JLabel jLabel1 = new JLabel("唱片编号:"); //定义显示的字 (只用来显示字)
JLabel jLabel2 = new JLabel("唱片名称:");
JLabel jLabel3 = new JLabel("歌手姓名:");
JButton jButton1 = new JButton("增加"); //定义按钮
JButton jButton2 = new JButton("取消");
String str;
public CDInfor() { //构造方法 程序启动的时候 或者调用这个类的时候执行(这里是程序启动)
try {
setDefaultCloseOperation(EXIT_ON_CLOSE); //天剑程序关闭的方法 要不然 你点关闭 界面没了 但是资源没释放
jbInit(); //调用jbInit()方法 用于实现事件
}
catch (Exception exception) { //错误捕捉
exception.printStackTrace();
}
}
public void jbInit()
{
Container cp = getContentPane(); //定义一个pane的容器
cp.setLayout(new BorderLayout()); //布局为边框布局
jButton1.addActionListener(this); //将按钮1 绑定事件
jButton2.addActionListener(this); //将按钮2 绑定事件
jTextArea1.setEditable(false); //将这个输入框设定为不可编辑
jScrollPane1.getViewport().add(jTextArea1); //滚动条和jTextArea1绑定
jPanel3.add(jLabel1); jPanel3.add(jTextField1); //将各个组件加入Jpanel里
jPanel4.add(jLabel2); jPanel4.add(jTextField2);
jPanel5.add(jLabel3); jPanel5.add(jTextField3);
jPanel6.add(jButton1); jPanel6.add(jButton2);
jPanel1.add(jScrollPane1);
jPanel2.add(jPanel3); jPanel2.add(jPanel4); jPanel2.add(jPanel5); jPanel2.add(jPanel6);
jPanel2.setPreferredSize(new Dimension(10, 150));
cp.add("Center",jPanel1);
cp.add("South",jPanel2);
}
public void actionPerformed(ActionEvent e) //实现事件监听
{
if(e.getSource()==jButton1) //如果当前是 按钮一的话
{
try {}
catch (Exception ex) {}
}
jTextField1.setText(""); //内容全部清空
jTextField2.setText("");
jTextField3.setText("");
}
public static void main(String[] args) throws Exception
{
CDInfor kk = new CDInfor(); //应为main是Static 所以 要new 本身类
kk.setSize(350,350); //设定大小
kk.setTitle("Please caculat:"); //设定标题栏文字
kk.setVisible(true); //是否显示 这个窗口
}
}
还不够详细么亲~ 采纳吧~~
首先需要明确一点的是管道流本身就不建议在一个线程中使用,这是因为向输出流中写的数据,都会存到输入流内部的一个1024字节大小的数组中,如果写的内容超过这个数组的大小,而且没有被输入流读取的话,输出流所在的线程就会等待,这时,如果是在同一个线程中,该线程就会死锁,这是sun在管道流中明确指明的,不推荐在同一个线程中使用。
至于你说的多个线程通过管道向另外一个线程发送数据,出现部分数据丢失的情况,没有代码不好分析具体原因。
大概看了下你的代码,撇开其他的问题先不管,在你的代码中所有ThrFindIndex中的PipedOutputStream都是connect到同一个PipedInputStream,而每个ThrFindIndex的run方法在运行完以后就会把这个PipedOutputStream进行close(),假设一个情景:第一个ThrFindIndex线程一直在运行,当他运行完了之后,这个PipedOutputStream就会被关闭,所有的管道也就都没用了,这必然会影响到其他使用该管道的线程。so我没有往下在看了,大致原因应该在这里。