您的位置:首页 > 编程语言 > Java开发

Java核心技术(多线程)四

2011-04-21 10:50 260 查看

同步器

java.util.concurrent包包含了几个能帮助人们管理相互合作的线程集的类。这些机制具有为线程之间的共用集结点模式提供的"预置功

能"。

CyclicBarrier类:允许线程集等待直至其中预订数目的线程到达一个公共障栅,然后可以选择执行一个处理障栅的动作。CyclicBarrier类是可循环的,可以在所有等待线程被释放后被重用。

public class CyclicBarrierDemo {
public static void main(String[] args) {
new CyclicBarrierDemo();
}
public CyclicBarrierDemo() {
barrier = new CyclicBarrier(barrierSize, new BarrierThread());
for (int i = 0; i < barrierSize; i++) {
new Thread(new PreThread(i)).start();
}
}
private static CyclicBarrier barrier = null;
private int barrierSize = 5;
class PreThread implements Runnable {
public PreThread(int count) {
this.count = count;
}
public void run() {
try {
while (true) {
System.out.println("count:" + count);
barrier.await();
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
private int count = 0;
}
class BarrierThread implements Runnable {
public void run() {
System.out.println("All threads have arrived!Do somethig!");
}
}
}


CountDownLatch类:允许线程集等待直到计数器减为0。

public class CountDownLatchDemo {
public static void main(String[] args) {
new CountDownLatchDemo();
}
public CountDownLatchDemo() {
downLatch = new CountDownLatch(downLatchSize);
for (int i = 0; i < downLatchSize; i++) {
new Thread(new PreWaitThread(i)).start();
}
for (int i = 0; i < downLatchSize; i++) {
new Thread(new PreCutThread()).start();
}
}
private static CountDownLatch downLatch = null;
private int downLatchSize = 5;

class PreCutThread implements Runnable{
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
downLatch.countDown();
}
}
class PreWaitThread implements Runnable {
public PreWaitThread(int count) {
this.count = count;
}
public void run() {
try {
System.out.println("begin:" + count);
downLatch.await();
System.out.println("end:" + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private int count = 0;
}
}


Exchanger类:允许两个线程在要交换的对象准备好时交换对象(两个线程工作在同一数据结构的两个实例上时,一个向实例添加数据而另一个从实例清除数据)。

SynchronousQueue类:允许一个线程把对象交给另一个线程。当一个线程调用SynchronousQueue类的put方法时,它会阻塞数据直到另一个线程调用take方法为止。与Exchanger类情况不同,数据仅仅沿一个方向传递。

public class ExchangerDemo {

public static void main(String[] args){
new ExchangerDemo();
}

public ExchangerDemo() {
exchanger = new Exchanger<ArrayList<Double>>();
produceArrayList = new ArrayList<Double>(size);
consumerArrayList = new ArrayList<Double>(size);
new Thread(new Produce()).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Consumer()).start();
}
private Exchanger<ArrayList<Double>> exchanger;
private ArrayList<Double> produceArrayList;
private ArrayList<Double> consumerArrayList;
private final int size = 10;

class Produce implements Runnable{
public void run() {
while(true){
if(produceArrayList.size() == 10){
try {
System.out.println("生产者等待消费!");
produceArrayList = exchanger.exchange(produceArrayList);
sign = !sign;
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
double d = Math.random();
System.out.println("生产者生产:" + d);
produceArrayList.add(d);
try {
Thread.sleep(sign?400:100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

private boolean sign = false;
}

class Consumer implements Runnable{
public void run() {
while(true){
if(!consumerArrayList.isEmpty()){
double d = consumerArrayList.remove(consumerArrayList.size()-1);
System.out.println("消费者消费:" + d);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
System.out.println("消费者等待生产!");
consumerArrayList = exchanger.exchange(consumerArrayList);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}


Semaphore类:允许线程集等待直到被允许继续运行为止。

public class SemaphoreDemo extends JFrame{

public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
public void run() {
new SemaphoreDemo().setVisible(true);
}
});
}

public SemaphoreDemo() {
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();
JButton button = new JButton("start");
panel.add(button);
add(panel, BorderLayout.NORTH);

component = new BallComponent();
add(component, BorderLayout.CENTER);
final Thread thread = new Thread(ballThread = new BallThread(new Ball(), component));

button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
JButton button = (JButton)event.getSource();
if(button.getText().equals("start")){
button.setText("stop");
thread.start();
}else if(button.getText().equals("stop")){
button.setText("continue");
ballThread.setStop();
}else{
button.setText("stop");
ballThread.setRun();
}
}
});
}

class BallThread implements Runnable{
public BallThread(Ball ball, BallComponent ballComponent) {
this.ball = ball;
this.ballComponent = ballComponent;
semaphore = new Semaphore(1);
}

public void setRun(){
run = true;
semaphore.release();
}

public void setStop(){
run = false;
}

public void run() {
while(true){
ball.move(ballComponent.getBounds());
ballComponent.setBall(ball);
if(run){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

private Ball ball;
private BallComponent ballComponent;
private Semaphore semaphore;
private volatile boolean run = true;
}

class BallComponent extends JComponent{

public void setBall(Ball ball){
this.ball = ball;
repaint();
}

public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
if(ball != null && ball.getShape()!=null)
g2.fill(ball.getShape());
}

private Ball ball;
}

class Ball{
public void move(Rectangle2D bounds){
x += dx;
y += dy;
if(x<bounds.getMinX()){
x = bounds.getMinX();
dx = -dx;
}
if(x + XSIZE >= bounds.getMaxX()){
x = bounds.getMaxX() - XSIZE;
dx = -dx;
}
if(y<bounds.getMinY()){
y = bounds.getMinY();
dy = -dy;
}
if(y+YSIZE>=bounds.getMaxY()){
y=bounds.getMaxY() - YSIZE;
dy = -dy;
}
}

public Ellipse2D getShape(){
return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
}

private static final int XSIZE = 15;
private static final int YSIZE = 15;
private double x = 0;
private double y = 0;
private double dx = 1;
private double dy = 1;
}

private static final int WIDTH = 500;
private static final int HEIGHT = 400;
private BallComponent component;
private BallThread ballThread;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: