英文:
Why just one of 5 threads pop elements from stack?
问题
public class ClassTest extends Thread{
public static Object lock = new Object();
public static LinkedList<Integer> stack;
public SortedSet<Integer> set = new TreeSet<>();
@Override
public void run(){
synchronized(lock){
while(!stack.isEmpty()){
set.add(stack.pop());
this.yield();
}
}
}
}
当我调用 start() 方法创建了5个线程后,为什么只有第一个线程弹出了所有的元素,而其他线程没有弹出任何元素?
我尝试过使用 wait() 和 notify() 方法,但没有起作用。
英文:
public class ClassTest extends Thread{
public static Object lock = new Object();
public static LinkedList<Integer> stack;
public SortedSet<Integer> set= new TreeSet<>();
@Override
public void run(){
synchronized(lock){
// try{
// this.wait();
// }
// catch(Exception e){
// e.printStackTrace();
// }
while(!stack.isEmpty()){
set.add(stack.pop());
this.yield();
// this.notifyAll();
}
}
}
When i start() 5 Threads why just first one pop all elements and others do not pop anyone?
I tried to use wait() and notify() methods, but that didn't help..
答案1
得分: 2
yield
方法不会释放锁。第一个进入同步块的线程将阻止其他线程进入,直到栈为空并且锁被释放。
以下是使用LinkedBlockingDeque
实现您所需的示例。
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.LinkedBlockingDeque;
class Main {
static final LinkedBlockingDeque<Integer> stack = new LinkedBlockingDeque<>();
static class Poller implements Runnable {
final Set<Integer> set = new HashSet<>();
@Override
public void run() {
Integer elem = stack.poll();
while (elem != null) {
set.add(elem);
System.out.printf("%s: %d\n", Thread.currentThread().getName(), elem);
elem = stack.poll();
}
}
}
public static void main(String args[]) {
for (int i = 0; i < 100; i++) {
stack.push(i);
}
for (int i = 0; i < 5; i++) {
new Thread(new Poller()).start();
}
}
}
英文:
The method yield
does not release locks. The very first thread that enters the synchronized block will keep other threads from entering until the stack is empty and the lock is released.
Here is an example that does what you want using LinkedBlockingDeque
.
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.LinkedBlockingDeque;
class Main {
static final LinkedBlockingDeque<Integer> stack = new LinkedBlockingDeque<>();
static class Poller implements Runnable {
final Set<Integer> set = new HashSet<>();
@Override
public void run() {
Integer elem = stack.poll();
while (elem != null) {
set.add(elem);
System.out.printf("%s: %d\n", Thread.currentThread().getName(), elem);
elem = stack.poll();
}
}
}
public static void main(String args[]) {
for (int i = 0; i < 100; i++) {
stack.push(i);
}
for (int i = 0; i < 5; i++) {
new Thread(new Poller()).start();
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论