线程同步问题
时间:2008-05-12 17:46:36
来源:论坛整理 作者: 编辑:chinaitzhe
private Vector <String> test = new Vector <String>();
public TestRunnable(int max) {
for (int i = 0; i < max; i ) {
test.add(i "");
}
}
public void run() {
while (test.size() > 0) {
System.out.println("read :" test.firstElement()
" thread name :" Thread.currentThread().getName());
test.removeElement(test.firstElement());
}
}
public static void main(String args[]) {
TestRunnable rc = new TestRunnable(1000);
ExecutorService exec = Executors.newFixedThreadPool(5);
for (int i = 0; i < 3; i ) {
exec.execute(rc);
}
exec.shutdown();
}
}
请问while里面需要同步吗??不需要的话,就报错Exception in thread "pool-1-thread-2" java.util.NoSuchElementException
at java.util.Vector.firstElement(Vector.java:447)
at TestRunnable.run(TestRunnable.java:22)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
vector不是线程同步的吗?为什么会出现这种情况啊?
网友回复:
答:
1)while(..){..}需要synchronized。
2)为什么呢?
Vector()是线程同步的,但它只保证:size() ,firstElement(),removeElement()这三个方法你调用时肯定是线程安全的,但不能认为:整个while中代码是线程安全的。否则当然会抛出java.util.NoSuchElementException 异常。这个异常是如何产生出来的?分析如下:
设Vector中只剩下一个元素了。这是:线程A首先运行到:while(test.size() > 0),此时条件成立(因为有一个元素),但是当线程A预备执行while中的第一条语句println()之前,CPU切换到线程B,此时线程B也开始执行while(test.size() > 0),此时条件也是成立的!线程B预备执行它的while中的第一条语句println()之前,CPU又被切换到线程A,此时线程A将它的while中语句全做完(此时Vector中已没有元素了),CPU又切换到线程B,线程B继续执行它的while中语句,当执行到test.firstElement() 时,由于Vector中已没有元素了,该方法将抛出:java.util.NoSuchElementException .
因此:按你现在的run()代码来说,你必须将整个while进行同步化,目的是:当线程A进行while时,CPU不能切换到竞争对手线程B中.
后果:假如整个while同步化,则整个程序的并发多线程的优势大大地削减了.
以上仅供你参考
网友回复:public class TestRunnable implements Runnable {
private Vector <String> test = new Vector <String>();
Lock lock = new ReentrantLock();
public TestRunnable(int max) {
for (int i = 0; i < max; i ) {
test.add(i "");
}
}
public void run() {
while (test.size() > 0) {
lock.lock();
System.out.println("read :" test.firstElement()
" thread name :" Thread.currentThread().getName());
test.removeElement(test.firstElement());
lock.unlock();
}
}
public static void main(String args[]) {
TestRunnable rc = new TestRunnable(1000);
ExecutorService exec = Executors.newFixedThreadPool(5);
for (int i = 0; i < 3; i ) {
exec.execute(rc);
}
exec.shutdown();
}
}
谢谢,不过我这样加锁还是不行
read :833 thread name :pool-1-thread-3
read :834 thread name :pool-1-thread-3
read :835 thread name :pool-1-thread-3
read :836 tException in thread "pool-1-thread-1" java.util.NoSuchElementException
at java.util.Vector.firstElement(Vector.java:447)
at TestRunnable.run(TestRunnable.java:20)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
hread name :pool-1-thread-3
read :837 thread name :pool-1-thread-3
read :838 thread name :pool-1-thread-3
read :839 thread name :pool-1-thread-3
read :840 thread name :pool-1-thread-3
read :841 thread name :pool-1-thread-3
read :842 thread name :pool-1-thread-3
read :843 thread name :pool-1-thread-3
read :844 thread name :pool-1-thread-3
只能同步整个while方法吗?
网友回复:答:这样加锁当然不行啊.你得将:条件检测test.size() > 0的while(...)加进去啊.否则是一样的后果啊.
网友回复:请问下,又没有别的方法,不同步整个while语句?我尝试test.removeElement(test.firstElement()); 语句后面加Thread.currentThread().sleep(10);或者synchronized(this){
if(test.size() > 0)
test.removeElement(test.firstElement());
}
这样似乎处理的不是很适当吧?
网友回复:
答:要仔细考虑一下.我的初步想法是:假如不同步整个while,则只能在firstElement())及removeElement()方法时,用test.size()先判.就像你写的那个代码.但要注重:synchronized(this){
if(test.size() > 0) 中的this应该是其它线程都共享的一个对象,像现在这样的this,指当前你的线程,肯定是不行的.
网友回复:呵呵,谢谢了,结贴~
关键字:线程,同步,问题,
上一篇:高手 求救 加分问题
下一篇:下面没有链接了











文章评论
共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面