javax.crypto.IllegalBlockSizeException:使用java8 parallelStream()

时间:2017-03-23 05:01:52

标签: java multithreading encryption thread-safety rsa

我的代码:

blotterlist.parallelStream().filter(p -> p.size() > 0).forEach(p -> decrypt(p));

private void decrypt(List<BlotterView> blotter) {
    for (BlotterView blotterView : blotter) {
        try {
            String s = crypto.encrypt(blotterView.getCreditCardNumber());
            crypto.decrypt(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

以上代码抛出异常。 但是不使用parallelStream,当我使用普通的for循环时,它没有抛出异常。

请注意。 Crypto是RSA算法的实现,方法不是Syncronized。

1 个答案:

答案 0 :(得分:1)

你说:“注意.Crypto是RSA算法的一种实现,方法不是同步的。”

我没有看到crypto对象传递到您的decrypt()方法,这强烈表明crypto是所有decrypt()调用共享的单个对象

如果是这种情况,那么crypto的方法不同步的事实可能是导致问题的原因。当您使用parallelStream()时,您正在设置允许使用多个线程来处理流的情况。这意味着可以从多个线程同时调用decrypt()。如果decrypt()的多个同时调用确实共享一个不同步的crypto对象,那么你很可能会遇到问题,因为你将使用多个线程不安全的对象线程。

相比之下,当您只使用stream()时,所有处理都在一个线程中进行,因此您很可能不会遇到任何问题。

以下是一个问题如何发生的例子(我并未声称这是具体的事情):

如果crypto不是线程安全的,那么crypto.decrypt()可能会在处理数据时将数据放入每个对象的缓冲区中。但是,当第一个线程仍在处理时,您再次从另一个线程调用crypto.decrypt()。这会覆盖缓冲区并基本上从第一次调用crypto.decrypt()下拉出地毯,导致错误。不是说这实际上是发生了什么,但它很可能类似于那个。