请各位高手指教,问题详情如下: 我是用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()之类的函数判断线程是否还处于活动状态.

解决方案 »

  1.   

    关键的函数如下: main()如下:         public static void main(String[] args) { 
                    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; 
            } 
      

  2.   

    线程实现函数: 
            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); 
                            }                        
                    } 
      }