请各位高手指教,问题详情如下:
我是用eclipse写的java程序,可以同时连接多个读卡器,对多张卡同时执行写卡操作。我对每个读卡器创建了一个线程,程序开始后,多个线程同时启动,轮流排队对每个读卡器进行写卡操作,写卡命令会在屏幕上显示,所以多张卡会在差不多的时间点写完。问题是我的程序同时写5张卡基本上没什么问题,但是同时写6张以上的卡时在写到50分钟左右的时候程序就死掉了,没有任何错误提示,都是在发了一条命令后不显示返回数据,然后程序的UI就不动了,但是电脑上的其他程序都是正常的。程序死掉之前的几分钟CPU的使用率为40-50%,居高不下,持续几分钟后,程序就不行了。
eclipse中的VM参数为-Xmx1024m,运行程序的电脑内存为2G。我把程序打包成可执行的jar文件,copy到别的机器上运行。
我的程序中没有对线程做终止处理,也没有调用isAlive()之类的函数判断线程是否还处于活动状态,关键的函数如下:
调用线程的函数:
private ListexecuteThreads = new ArrayList();
public JButton getExeBtn() {
if (exeBtn == null) {
exeBtn = new JButton("Execute");
exeBtn.setBounds(new Rectangle(190, 332, 90, 30));
exeBtn.setBackground(Color.green);
exeBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
exeBtn.setEnabled(false);
exeBtn.setBackground(Color.red);
refreshBtn.setEnabled(false);
//connBtn.setEnabled(false);
countNum = 0;
errorNum=0;
AddorClearTabPane addorclearTabPane =new AddorClearTabPane();
if(listModel.size() == 0){
JOptionPane.showMessageDialog(null,"没有连接读卡器,请确认。");
exeBtn.setEnabled(true);
refreshBtn.setEnabled(true);
return;
}
if(executeThreads.size() > 0)
TabPane.clearRunLog(executeThreads.size());
else{
String readerName;
int num = 0;
addorclearTabPane.clearTab(logTabbedPane);
for(int i = 0;i < 10;i++){
if(recReaderName ==null
|| recReaderName.length() ==0)
continue;
readerName = recReaderName;
String temp =listModel.get(i).toString();
addorclearTabPane.addTab(logTabbedPane,num,temp.substring(temp.indexOf("--")+2));
recordReaderName.put(readerName,num);
num++;
}
}
if(recordReaderName.size() == 0){
exeBtn.setBackground(Color.green);
exeBtn.setEnabled(true);
return;
}
if(seqCount == 0){
if(!InitialCard()){
exeBtn.setBackground(Color.green);
exeBtn.setEnabled(true);
return;
}
}
end();
executeThreads.clear();
for (int i = 0; i <recordReaderName.size(); i++)
executeThreads.add(new ExecuteThread(recReaderName));
for (ExecuteThread workerThread : executeThreads) {
workerThread.start();
}
}
});
}
return exeBtn;
}
线程实现函数:
public class ExecuteThread extends Thread {
String readerName;
public ExecuteThread(String name) {
readerName = name;
}
public void run() {
execute();
}
privatesynchronized void execute(){
countNum ++;
if(!connPCSCReader(readerName))
return;
//send "verify" command
verifyCard(readerName);
if(!flag)
return;
//Erase
eraseCard(readerName);
if(!flag)
return;
//send Pflash Base and Write
for(int i = 2; i < 6; i++){
writePflash(readerName,i);
if(!flag)
return;
}
TabPane.writeRunLog(readerName, recReaderName, "Write data now,please wait...", "green");
//verify
verifyCard(readerName);
if(!flag)
return;
updataDflash(readerName);
String retStr;
TabPane.writeRunLog(readerName, recReaderName, "\nPflash Base:","blue");
String cmd = "00 30 00 02 00";
TabPane.writeRunLog(readerName, recReaderName, " "+cmd,"black");
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr))
return;
TabPane.writeRunLog(readerName, recReaderName,"Pflash Write:" ,"blue");
TabPane.writeRunLog(readerName, recReaderName,"00 38 00 00 "+length,"black");
TabPane.writeRunLog(readerName, recReaderName,chipData02.get(0),"black");
retStr = sendCMD(readerName,"00 38 00 00 "+length + chipData02.get(0));
if(!verify(readerName,retStr))
return;
retStr = closePCSCReader(readerName);
if(retStr.indexOf("46 61 69 6C") != -1 ||
retStr.indexOf("Fail") != -1){
//
JOptionPane.showMessageDialog(null, readerName+"\n断开卡失败.");
TabPane.writeRunLog(readerName, recReaderName," 断开卡失败"+readerName,"red");
return;
}
if(!connPCSCReader(readerName))
return;
//
//CheckSum
TabPane.writeRunLog(readerName, recReaderName, "CheckSum:","black");
cmd = "A0 BA 00 00 04"+checkSum;
TabPane.writeRunLog(readerName, recReaderName," "+cmd,"black");
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr)){
return;
}
//
retStr = closePCSCReader(readerName);
if(retStr.indexOf("46 61 69 6C") != -1 ||
retStr.indexOf("Fail") != -1){
//JOptionPane.showMessageDialog(null, readerName+"\n断开卡失败.");
TabPane.writeRunLog(readerName, recReaderName," 断开卡失败"+readerName,"red");
return;
}
if(!connPCSCReader(readerName))
return;
//
//INS: Verify ADM4
TabPane.writeRunLog(readerName, recReaderName, "Verify ADM4:","blue");
cmd = "A020000E08"+adm4; //S9000
TabPane.writeRunLog(readerName, recReaderName, " "+cmd,"black");
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr))
return;
//INS: Verify ADM1
TabPane.writeRunLog(readerName, recReaderName, "Verify ADM1:","blue");
cmd = "A0 20 000B 08 0000000000000000"; //S9000
TabPane.writeRunLog(readerName, recReaderName, " "+cmd,"black");
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr))
return;
//INS: Verify CHV2
TabPane.writeRunLog(readerName, recReaderName, "Verify CHV2:","blue");
cmd = "A0 20 0002 08 35363738FFFFFFFF"; //S9000
TabPane.writeRunLog(readerName, recReaderName, " "+cmd, "black");
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr))
return;
//INS: Select 3F00
TabPane.writeRunLog(readerName, recReaderName, "Select 3F00:", "blue");
cmd = "A0A40000023F00" ;//S9F16/)
TabPane.writeRunLog(readerName, recReaderName, " "+cmd, "black");
retStr = sendCMD(readerName,cmd);
TabPane.writeRunLog(readerName, recReaderName, " "+retStr, "black");
if(!verify(readerName,retStr))
return;
//ICCID
TabPane.writeRunLog(readerName, recReaderName, "ICCID:", "blue");
cmd = "a0a40000023f00";
TabPane.writeRunLog(readerName, recReaderName, " "+cmd, "black");
retStr = sendCMD(readerName,cmd);
TabPane.writeRunLog(readerName, recReaderName, " "+retStr, "black");
if(!verify(readerName,retStr))
return;
cmd = "a0a40000022FE2" ;
TabPane.writeRunLog(readerName, recReaderName, " "+cmd, "black");
retStr = sendCMD(readerName,cmd);
TabPane.writeRunLog(readerName, recReaderName, " "+retStr, "black");
if(!verify(readerName,retStr))
return;
String strTemp="";
if(seqCount == 0){
cmd = "A0D600000A" + seqence;
}else{
int countNo = Integer.parseInt(seqence.substring(12),16) + seqCount;
strTemp = Integer.toHexString(countNo).toUpperCase();
while(strTemp.length() < 8)
strTemp = "0" + strTemp;
cmd = "A0D600000A" + seqence.substring(0,12)+strTemp;
}
seqCount ++;
TabPane.writeRunLog(readerName, recReaderName, " "+cmd, "black");
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr)){
seqCount --;
return;
}
strTemp = cmd.substring(10);
TabPane.writeRunLog(readerName, recReaderName, "Read seqence:", "blue");
cmd = "A0 B0 00 00 0a";
TabPane.writeRunLog(readerName, recReaderName, " "+cmd, "black");
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr)) {
seqCount --;
return;
}
retStr = retStr.replace(" ", "");
if(retStr.indexOf(strTemp) != -1)
{
String ICCIDret = retStr.toString();
ICCIDret = ICCIDret.substring(0,20);
//
JOptionPane.showMessageDialog(null, readerName + "\nISIM卡:"+strTemp+"制作完成.");
TabPane.writeRunLog(readerName, recReaderName," ICCID:"+ICCIDret,"green");
TabPane.writeRunLog(readerName, recReaderName," SIM卡制作完成"+readerName,"green");
}
else {
seqCount --;
}
retStr = closePCSCReader(readerName);
if(retStr.indexOf("46 61 69 6C") != -1 ||
retStr.indexOf("Fail") != -1){
//
JOptionPane.showMessageDialog(null, readerName+"\n断开卡失败.");
TabPane.writeRunLog(readerName, recReaderName,"断开卡失败,这不是个错误,SIM卡已制作完成"+readerName,"green");
return;
}
if(countNum == recordReaderName.size()) {
exeBtn.setBackground(Color.green);
exeBtn.setEnabled(true);
}
}
}
写5张卡的时间一般都控制在50分钟之内,所以是成功的,但是超过5张卡,时间也就超过了50分钟,到50分钟左右时程序就死掉了。读卡器都是连在一个带电源的USB hub上,所以排除了USB口供电不足的问题。
我刚开始用java,属于菜鸟一个,请高手帮忙看一下程序,是不是程序里面存在了什么缺陷或者是参数设置的不对?多谢了!
|