public class BlockQueueCommuncationTest {
/**
用两个具有1个空间的队列来实现同步通知的功能。
子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 接着再回到主线程又循环100,如此循环50次,请写出程序。
* 我们先来实现这样的效果: 先实现2个线程都执行语句。 一个线程在执行的时候其它的线程不会去打断他的执行。
* 我们没有使用互斥。主线程在执行的时候,还没有执行完就被子线程给打断了
*/
public static void main(String[] args) {
final Business busi = new Business();
// 子线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
busi.sub(i); // 调用相关联的类身上的方法
}
}
}).start();
// 主线程
for (int i = 1; i <= 50; i++) {
busi.main(i); // 调用相关联的类身上的方法
}
}
}
class Business {
//我们要使用阻塞队列的形式来实现主线程和子线程之间的通信
//让子线程先执行。就意味着主线程默认是阻塞的状态。
//阻塞队列时:队列处于full时,若再执行put方法,执行该操作的线程会进行阻塞,
//阻塞队列时:队列处于empty时,若再执行empty方法,执行该操作的线程会进行阻塞,
private BlockingQueue<Integer> main=new ArrayBlockingQueue<Integer>(1); //里面只有一个元素.
private BlockingQueue<Integer> sub=new ArrayBlockingQueue<Integer>(1); //里面只有一个元素.
//既然是想让主线程处于阻塞。我们就要默认给main队列添加一个数据
//这样在main方法中再添加的时候它就处于阻塞了
{ //可能没有人看到过这种形式
//其实这种形式是匿名构造方法。它是优先于所有的构造方法之前调用。在构造方法调用之前。匿名构造方法是
//要先调用的。构造方法调用几次,匿名构造方法就调用几次。我们的static它是随着类的加载而加载。而且
//只会执行一次。
try {
main.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void sub(int i) {
try {
sub.put(i); //子线程执行数据。如果队列为满的。它就会进行阻塞
for (int j = 1; j <= 10; j++) {
System.out.println("sub thread sequence of:" + j + ",loop of:"
+ i);
}
main.take(); //通知主线程执行取数据
} catch (Exception e) {
// TODO: handle exception
}
}
public synchronized void main(int i) {
try {
main.put(1); //因为我们默认为当前的队列添加了数据。所以当前集合是满的。这里在第一次的时候会进入阻塞。
for (int j = 1; j <= 100; j++) {
System.out.println("main thread sequence of:" + j + ",loop of:"
+ i);
}
sub.take(); //通知子线程取数据
} catch (Exception e) {
// TODO: handle exception
}
}
}
《黑马程序员》 使用阻塞队列实现同步通知
最新推荐文章于 2020-12-21 14:07:46 发布