java多线程共享Vector抛异常 本帖最后由 iamascv 于 2013-11-14 17:05:38 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 线程安全也是相对的while (!vv.isEmpty()) 判断和下面的remove动作不是原子操作,也就是没有共享锁。你可以这样理解:Thread1 while (!vv.isEmpty()) true 。进去后,正好Thread2 也进去了,并且先于Thread1 Remove了这个时候就报错了。java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0 Vector的线程安全,指的是:它的任意一个public的方法是现场安全的。你的这种“先空,再操作”的逻辑,里面涉及了Vector的2个方法:isEmpty()和remove()。这样会造成并发的状态不一致问题。你可以看看《java并发编程》这本书,里面对你遇到的这类问题进行了详细的阐述。 Vector是线程安全的但你的代码线程不安全啊。 状态不一致,冲突了。 看了一下你的代码。你的这种设计,不就是“生产者-消费者”模式么?为什么不采用具有“阻塞”的并发队列呢?比如:BlockingQueue.关于“生产者-消费者”,我这里有个例子,你可以看看:http://kanpiaoxue.iteye.com/admin/blogs/1974681 嗯,明白了不过为什么Thread-1抛异常之后,后面还在执行呢? 刚开始研究多线程,还不太熟悉concurrent包,以后多关注 为什么?看看你的代码:catch (Exception e) { e.printStackTrace();}发现了么?你的Exception都被你catch了。你在catch之后,也没有终止线程,只是简单的打印出了Exception的堆栈信息。如果想让这个线程结束,你可以在 catch 里面在抛出这个异常,或者把你的try...catch...去掉,你就会发现你的线程终止运行并退出了。如果你要经常用到并发编程,推荐你还是看看《Java并发编程》这本书吧。不明白并发的机制,自己写出的程序,自己都不敢用,提心吊胆的。 你用的try catch 是捕获异常,不是抛出异常。 Vector本身是线程安全的。但是你的操作不安全。你catch的异常只是做打印,所以继续走System.out.println(Thread.currentThread().getName() + " ****************crashed****************"); e.printStackTrace();如果你捕捉到此异常System.exit(0);那程序就退出了 java 保存 窗口对象 ExceptionListener的问题 0X4040,0X2001,0x0000是什么意思呢? 在LINUX下对文件的操作问题! 为什么会出现异常? 在执行swing程序中碰到的编译问题? 请教关于jbuilder的"设计时运行"(我这么叫的)的机制?? 动态设字体问题? 请问模态对话框和非模态对话框有什么不同? 请问websphere对外提供服务的时候需要什么端口? socket多人通信的问题。 java 调用.net webservice 需要传实体类,客户端怎么写?.net 的webservice需要修改什么吗?
while (!vv.isEmpty()) 判断和下面的remove动作不是原子操作,也就是没有共享锁。
你可以这样理解:
Thread1 while (!vv.isEmpty()) true 。进去后,正好Thread2 也进去了,并且先于Thread1 Remove了
这个时候就报错了。java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0
关于“生产者-消费者”,我这里有个例子,你可以看看:
http://kanpiaoxue.iteye.com/admin/blogs/1974681
不过为什么Thread-1抛异常之后,后面还在执行呢?
为什么?看看你的代码:catch (Exception e) {
e.printStackTrace();
}发现了么?你的Exception都被你catch了。你在catch之后,也没有终止线程,只是简单的打印出了Exception的堆栈信息。如果想让这个线程结束,你可以在 catch 里面在抛出这个异常,或者把你的try...catch...去掉,你就会发现你的线程终止运行并退出了。
如果你要经常用到并发编程,推荐你还是看看《Java并发编程》这本书吧。不明白并发的机制,自己写出的程序,自己都不敢用,提心吊胆的。
你用的try catch 是捕获异常,不是抛出异常。
但是你的操作不安全。你catch的异常只是做打印,所以继续走
System.out.println(Thread.currentThread().getName()
+ " ****************crashed****************");
e.printStackTrace();如果你捕捉到此异常System.exit(0);那程序就退出了