多线程Demo学习(使用阻塞队列实现线程同步,新建有返回值的线程)
一.使用阻塞队列实现线程同步
实际开发中使用java.util.concurrent包将有助于简化开发。 本Demo使用其中的LinkedBlockingQueue类来解决生产者消费者问题。
首先我们先了解下这个API:LinkedBlockingQueue< E >是一个基于已连接节点的,范围任意的阻塞队列,此队列按照先进先出排序元素。 队列的头部是在队列中时间最长的元素,队列的尾部是在队列中时间最短的元素,新元素插入到队列的尾部。获取队列元素的操作只会获取头部元素,且如果队列满了或者为空会进入阻塞状态。
方法名 | 作用 |
---|---|
LinkedBloockingQueue() | 创建一个容量为Integer.MAX_VALUE的LinkedBlockQueue |
put(E e) | 在队尾添加一个元素,如果队列满则阻塞 |
size() | 返回队列中的元素个数 |
take() | 移除并返回头部元素,如果队列空则阻塞 |
然后我们先看一下Demo的代码并运行,看下效果:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.UIManager;
import java.awt.Font;
public class ProducerAndConsumerFrame extends JFrame {
private static final long serialVersionUID = -1644485036183526329L;
private JPanel contentPane;
private BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
private final int size = 10;
private JTextArea producerTextArea;
private JTextArea consumerTextArea;
private JTextArea storageTextArea;
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ProducerAndConsumerFrame frame = new ProducerAndConsumerFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ProducerAndConsumerFrame() {
setTitle("\u4F7F\u7528\u963B\u585E\u961F\u5217\u5B9E\u73B0\u7EBF\u7A0B\u540C\u6B65");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JPanel buttonPanel = new JPanel();
contentPane.add(buttonPanel, BorderLayout.SOUTH);
JButton startButton = new JButton("\u5F00\u59CB\u751F\u4EA7");
startButton.setFont(new Font("微软雅黑", Font.PLAIN, 16));
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
do_startButton_actionPerformed(arg0);
}
});
buttonPanel.add(startButton);
JPanel resultPanel = new JPanel();
contentPane.add(resultPanel, BorderLayout.CENTER);
resultPanel.setLayout(new GridLayout(1, 3, 5, 5));
JPanel producerPanel = new JPanel();
resultPanel.add(producerPanel);
producerPanel.setLayout(new BorderLayout(0, 0));
JLabel producerLabel = new JLabel("\u751F\u4EA7\u8005");
producerLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
producerLabel.setHorizontalAlignment(SwingConstants.CENTER);
producerPanel.add(producerLabel, BorderLayout.NORTH);
JScrollPane producerScrollPane = new JScrollPane();
pro