Java 线程问题查错

在最近的项目中,遇到一个关于线程的问题:系统中包括许多线程,这些线程主要是获取不同的数据,但每次过一阵子就发现线程获取的数据混乱了,还有就是可能一个线程突然获取不到数据了。针对这些情况进行线程问题查错。

  • 线程获取数据混乱
    一般线程获取的数据混乱,主要由于线程直接数据/资源共享导致的,所以这个问题需要查看代码是否存在线程间数据共享的问题,最后发现以下问题:

    
    public static File replace(String inFileName, Map<String,String> paras)
            throws IOException, UnsupportedEncodingException {
        File inFile = new File(inFileName);
        BufferedReader in = new BufferedReader(new InputStreamReader(
                new FileInputStream(inFile), "utf-8"));
        File outFile = new File(inFile + ".tmp");
        PrintWriter out = new PrintWriter(new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(outFile), "utf-8")));
        String reading=null;
        Entry<String,String> entry=null;
        while ((reading = in.readLine()) != null) {//一行行替换需要传入的参数
            Iterator it =paras.entrySet().iterator();
            while(it.hasNext()){//遍历需要传入的参数
                entry= (Entry<String,String>) it.next();
                reading=reading.replaceAll(entry.getKey(), entry.getValue());
            }
            out.println(reading);
        }
        out.close();
        in.close();
        //infile.delete(); //删除源文件
        //outfile.renameTo(infile); //对临时文件重命名
        return outFile;
    }

    这部分代码实现了对请求参数的替换,是使用了一个临时文件进行替换的,而文件是在多个线程直接是共享的,所以在参数替换过程中将会发送参数错误。

  • 一个线程突然获取不到数据
    一个线程突然间获取不到数据,可能存在的原因包括线程存在未处理的异常,线程抛出异常后导致线程直接挂了,或者是多个线程访问同一资源导致多个线程都block了等。为了确定是什么原因导致的,我们使用java自带的jvisualvm工具查看线程信息。以下是Tomcat的所有线程:
    Tomcat的所有线程

    点击线程Dump,查看每一个线程的实时情况,实时情况数据如下:
    线程Dump情况

找到出问题的线程的信息,发现线程处于BLOCK状态,已经阻塞了,而正常的进程一般处于RUNNING、WAITING等状态,而具体导致处于BLOCK的代码为以下代码段:

 public static byte[] readInputStream(InputStream inStream) throws Exception{
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while( (len = inStream.read(buffer)) !=-1 ){
            outStream.write(buffer, 0, len);
        }
        byte[] data = outStream.toByteArray();//网页的二进制数据
        outStream.close();
        inStream.close();
        return data;
    }

存在原因为输出流没有结束,一直处于while死循环中(具体原因可能是数据过长)。于是选择改成wsimport方式获取web service数据,从而避免自己拼串,组织参数去请求数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值