public class TestRunnable implements Runnable {
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不是线程同步的吗?为什么会出现这种情况啊?
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同步化,则整个程序的并发多线程的优势大大地削减了.
以上仅供你参考
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方法吗?
if(test.size() > 0)
test.removeElement(test.firstElement());
}
这样好像处理的不是很适当吧?
if(test.size() > 0) 中的this应该是其它线程都共享的一个对象,像现在这样的this,指当前你的线程,肯定是不行的.