为什么只有其中一个线程从堆栈中弹出元素?

huangapple go评论81阅读模式
英文:

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&lt;Integer&gt; stack;
	public SortedSet&lt;Integer&gt; set= new TreeSet&lt;&gt;();
	@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&lt;Integer&gt; stack = new LinkedBlockingDeque&lt;&gt;();
	
	
	static class Poller implements Runnable {
		final Set&lt;Integer&gt; set = new HashSet&lt;&gt;();
		
		@Override
		public void run() {
			Integer elem = stack.poll();
			while (elem != null) {
				set.add(elem);
				System.out.printf(&quot;%s: %d\n&quot;, Thread.currentThread().getName(), elem);
				elem = stack.poll();
			}
		}
	}
	
	
    public static void main(String args[]) {
    	for (int i = 0; i &lt; 100; i++) {
    		stack.push(i);
    	}
    	for (int i = 0; i &lt; 5; i++) {
    		new Thread(new Poller()).start();
    	}
    }
}

huangapple
  • 本文由 发表于 2020年8月17日 04:56:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63441854.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定