请各位高手指教,问题详情如下: 我是用eclipse写的java程序,可以同时连接多个读卡器,对多张卡同时执行写卡操作。我对每个读卡器创建了一个线程,程序开始后,多个线程同时启动,轮流排队对每个读卡器进行写卡操作,写卡命令会在屏幕上显示,所以多张卡会在差不多的时间点写完。
问题是我的程序同时写5张卡基本上没什么问题,但是同时写6张以上的卡时在写到40分钟左右的时候,CPU的使用率就逐渐累加,从10%到20%,然后到40%-50%,之后就会死掉了,没有任何错误提示,都是在发了一条命令后不显示返回数据,然后程序的UI就不动了,但是电脑上的其他程序都是正常的。程序死掉时偶尔会有卡片已经写卡成功,但多数情况下是所有的卡片都没有完成写卡。 eclipse中的VM参数为-Xmx1024m,运行程序的电脑内存为2G。我把程序打包成可执行的jar文件,copy到别的机器上运行。
我自己的机器是2G内存,其他配置比较高,有时候能同时写成功6张和6张以上的卡,但是在另外一台老机器上就不行,那台机器的内存也是2G,但是其他的配置就比较低了。 读卡器都是连在一个带电源的USB hub上,所以排除了USB口供电不足的问题。
还有写卡的数据量挺大的,每张卡要写4块程序区,1块数据区,每块区域都是从0000到FFFF,每条命令写0x80个字节,所以每张卡要发2500多次命令。
我的程序中没有对线程做终止处理,也没有调用isAlive()之类的函数判断线程是否还处于活动状态.
问题是我的程序同时写5张卡基本上没什么问题,但是同时写6张以上的卡时在写到40分钟左右的时候,CPU的使用率就逐渐累加,从10%到20%,然后到40%-50%,之后就会死掉了,没有任何错误提示,都是在发了一条命令后不显示返回数据,然后程序的UI就不动了,但是电脑上的其他程序都是正常的。程序死掉时偶尔会有卡片已经写卡成功,但多数情况下是所有的卡片都没有完成写卡。 eclipse中的VM参数为-Xmx1024m,运行程序的电脑内存为2G。我把程序打包成可执行的jar文件,copy到别的机器上运行。
我自己的机器是2G内存,其他配置比较高,有时候能同时写成功6张和6张以上的卡,但是在另外一台老机器上就不行,那台机器的内存也是2G,但是其他的配置就比较低了。 读卡器都是连在一个带电源的USB hub上,所以排除了USB口供电不足的问题。
还有写卡的数据量挺大的,每张卡要写4块程序区,1块数据区,每块区域都是从0000到FFFF,每条命令写0x80个字节,所以每张卡要发2500多次命令。
我的程序中没有对线程做终止处理,也没有调用isAlive()之类的函数判断线程是否还处于活动状态.
try{
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}catch(Exception e){
throw new RuntimeException(e);
}
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
WriteCardByPCSCMain application = new WriteCardByPCSCMain();
application.getJFrame().setVisible(true);
}
});
}
调用线程的函数:
private List <ExecuteThread> executeThreads = new ArrayList <ExecuteThread>(); 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();
}
private synchronized 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
cmd = "A0 20 0002 08 35363738FFFFFFFF"; //S9000
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr))
return;
//INS: Select 3F00
cmd = "A0A40000023F00" ;//S9F16/)
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr))
return;
//ICCID
cmd = "a0a40000023f00";
retStr = sendCMD(readerName,cmd);
if(!verify(readerName,retStr))
return;
cmd = "a0a40000022FE2" ;
retStr = sendCMD(readerName,cmd);
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);
}
}
}