Java 为什么只有5个线程中的一个从堆栈中弹出元素? 公共类类测试扩展线程{ 公共静态对象锁=新对象(); 公共静态链接列表堆栈; 公共分类集=新树集(); @凌驾 公开募捐{ 已同步(锁定){ //试一试{ //这个。等等(); // } //捕获(例外e){ //e.printStackTrace(); // } 而(!stack.isEmpty()){ set.add(stack.pop()); 这个。屈服(); //this.notifyAll(); } } }
当我启动()5个线程时,为什么第一个线程会弹出所有元素,而其他线程不会弹出任何元素?Java 为什么只有5个线程中的一个从堆栈中弹出元素? 公共类类测试扩展线程{ 公共静态对象锁=新对象(); 公共静态链接列表堆栈; 公共分类集=新树集(); @凌驾 公开募捐{ 已同步(锁定){ //试一试{ //这个。等等(); // } //捕获(例外e){ //e.printStackTrace(); // } 而(!stack.isEmpty()){ set.add(stack.pop()); 这个。屈服(); //this.notifyAll(); } } },java,multithreading,synchronization,thread-safety,Java,Multithreading,Synchronization,Thread Safety,当我启动()5个线程时,为什么第一个线程会弹出所有元素,而其他线程不会弹出任何元素? 我尝试使用wait()和notify()方法,但没有任何帮助。方法yield不会释放锁。进入同步块的第一个线程将阻止其他线程进入,直到堆栈为空并释放锁为止 下面是一个使用LinkedBlockingDeque实现所需功能的示例 import java.util.HashSet; 导入java.util.Set; 导入java.util.concurrent.LinkedBlockingDeque; 班长{ 静
我尝试使用wait()和notify()方法,但没有任何帮助。方法
yield
不会释放锁。进入同步块的第一个线程将阻止其他线程进入,直到堆栈为空并释放锁为止
下面是一个使用
LinkedBlockingDeque
实现所需功能的示例
import java.util.HashSet;
导入java.util.Set;
导入java.util.concurrent.LinkedBlockingDeque;
班长{
静态最终LinkedBlockingDeque堆栈=新LinkedBlockingDeque();
静态类轮询器实现可运行{
最终集=新的HashSet();
@凌驾
公开募捐{
整数elem=stack.poll();
while(elem!=null){
集合。添加(元素);
System.out.printf(“%s:%d\n”,Thread.currentThread().getName(),elem);
elem=stack.poll();
}
}
}
公共静态void main(字符串参数[]){
对于(int i=0;i<100;i++){
堆栈推送(i);
}
对于(int i=0;i<5;i++){
新线程(新轮询器()).start();
}
}
}
方法yield
不会释放锁。进入同步块的第一个线程将阻止其他线程进入,直到堆栈为空并释放锁
下面是一个使用
LinkedBlockingDeque
实现所需功能的示例
import java.util.HashSet;
导入java.util.Set;
导入java.util.concurrent.LinkedBlockingDeque;
班长{
静态最终LinkedBlockingDeque堆栈=新LinkedBlockingDeque();
静态类轮询器实现可运行{
最终集=新的HashSet();
@凌驾
公开募捐{
整数elem=stack.poll();
while(elem!=null){
集合。添加(元素);
System.out.printf(“%s:%d\n”,Thread.currentThread().getName(),elem);
elem=stack.poll();
}
}
}
公共静态void main(字符串参数[]){
对于(int i=0;i<100;i++){
堆栈推送(i);
}
对于(int i=0;i<5;i++){
新线程(新轮询器()).start();
}
}
}
Ohh是的,你是对的..谢谢..那么,你建议怎么做,也许其他方式?@DevJava首先,我建议接受答案,因为这是你问题的答案。-)然后我建议不要在这里使用synchronized
。你可以使用在方法上同步的数据结构,例如LinkedBlockingDeque
。然后,只要poll
不返回null
,所有线程都可以对其调用poll
。请注意,您还需要为set
使用同步数据结构。感谢您的回答。。很抱歉打扰您,但是有没有办法使用同步块(可能使用wait()和notify()来实现此目的)方法,或者这是不可能的..再次感谢..@DevJava我刚刚添加了一个带有LinkedBlockingDeque
的示例。这并不像你想象的那么难。是的,有一种方法可以使用wait
和notify
来实现,但它基本上是在堆栈上的每个访问周围实现同步的。你知道吗知道我的意思吗?在这里使用wait
/notify
是没有意义的。哦,是的,你是对的。谢谢。那么,你建议怎么做,或者其他方式?@DevJava首先,我建议接受答案,因为这是你问题的答案。;-)然后我建议不要在这里使用synchronized
。您可以使用在方法上同步的数据结构,例如LinkedBlockingDeque
。然后,只要poll
不返回null
,所有线程都可以对其调用poll
。请注意,您还需要为使用同步数据结构e> 设置
。谢谢您的回答。很抱歉打扰您,但是有没有办法使用同步块(可能使用wait()和notify()来实现这一点方法,或者这是不可能的..再次感谢..@DevJava我刚刚添加了一个带有LinkedBlockingDeque
的示例。这并不像你想象的那么难。是的,有一种方法可以使用wait
和notify
来实现,但它基本上是在堆栈上的每个访问周围实现同步的。你知道吗知道我的意思吗?在这里使用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();
}
}
}