java stack 线程安全_java 对线程安全支持有哪些?

阻塞队列,BlockingQueue。它提供了put和take方法,在队列不满足各自条件时将产生阻塞

BlockingQueue使用示例,生产者-消费者

public static void main(String[] args) throws Exception {

BlockingQueue queue = new ArrayBlockingQueue(1024);

Producer producer = new Producer(queue);

Consumer consumer = new Consumer(queue);

new Thread(producer).start();

new Thread(consumer).start();

}

}

public class Producer implements Runnable{

protected BlockingQueue queue = null;

public Producer(BlockingQueue queue) {

this.queue = queue;

}

public void run() {

try {

queue.put("1");

Thread.sleep(1000);

queue.put("2");

Thread.sleep(2000);

queue.put("3");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public class Consumer implements Runnable{

protected BlockingQueue queue = null;

public Consumer(BlockingQueue queue) {

this.queue = queue;

}

public void run() {

try {

System.out.println(queue.take());

System.out.println("Wait 1 sec");

System.out.println(queue.take());

System.out.println("Wait 2 sec");

System.out.println(queue.take());

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

输出为

1

Wait 1 sec

2

Wait 2 sec

3

闭锁

CountDownLatch。使多个线程等待一组事件发生,它包含一个计数器,表示需要等待的事件的数量,每发生一个事,就递减一次,当减为0时,所有事情发生,允许“通行”

CountDownLatch示例:

public class TestHarness{

public long timeTasks(int nThreads,final Runnable task) throws InterruptedException {

final CountDownLatch startGate = new CountDownLatch(1);

final CountDownLatch endGate = new CountDownLatch(nThreads);

for (int i=0;i

Thread t = new Thread(){

public void run(){

try {

startGate.await();

try {

task.run();

}finally {

endGate.countDown();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

};

t.start();

}

long start = System.nanoTime();

startGate.countDown();

endGate.await();

long end=System.nanoTime();

return end-start;

}

}

启动门使主线程能够同时释放所有的工作线程,结束门使得主线程能够等待最后一个线程执行完

FutureTask。Future.get的如果任务执行完成,则立即返回,否则将阻塞直到任务完结,再返回结果或者是抛出异常

信号量,Semaphore 。它管理着一组虚拟的许可,许可的数量可通过构造函数指定,在执行操作时首先获得许可,并在使用后释放许可,如果没有,那么accquire将阻塞直到有许可。

Semaphore示例

public class BoundedHashSet{

private final Set set;

private final Semaphore sem;

public BoundedHashSet(int bound) {

this.set = Collections.synchronizedSet(new HashSet());

this.sem = new Semaphore(bound);

}

public boolean add(T o) throws InterruptedException {

sem.acquire();

boolean wasAdded = false;

try {

wasAdded = set.add(o);

return wasAdded;

}finally {

if (!wasAdded){

sem.release();

}

}

}

public boolean remove(Object o){

boolean wasRemoved = set.remove(o);

if(wasRemoved){

sem.release();

}

return wasRemoved;

}

}

栅栏。它能阻塞一组线程直到某个事件发生。 与闭锁的区别:

所有线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其它线程。

闭锁一旦进入终止状态,就不能被重置,它是一次性对象,而栅栏可以重置

CyclicBarrier。可以使一定数量的参与方反复地在栅栏位置汇集

CyclicBarrier使用示例

public static void main(String[] args) {

//第k步执行完才能执行第k+1步

CyclicBarrier barrier = new CyclicBarrier(3,new StageKPlusOne());

StageK[] stageKs = new StageK[3];

for (int i=0;i<3;i++){

stageKs[i] = new StageK(barrier,"k part "+(i+1));

}

for (int i=0;i<3;i++){

new Thread(stageKs[i]).start();

}

}

class StageKPlusOne implements Runnable{

@Override

public void run() {

System.out.println("stage k over");

System.out.println("stage k+1 start counting");

}

}

class StageK implements Runnable{

private CyclicBarrier barrier;

private String stage;

public StageK(CyclicBarrier barrier, String stage) {

this.barrier = barrier;

this.stage = stage;

}

@Override

public void run() {

System.out.println("stage "+stage+" counting...");

try {

TimeUnit.MILLISECONDS.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("stage "+stage+" count over");

try {

barrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

}

}

输出为

stage k part 1 counting...

stage k part 3 counting...

stage k part 2 counting...

stage k part 2 count over

stage k part 3 count over

stage k part 1 count over

stage k over

stage k+1 start counting

Exchanger。它是一种两方栅栏,各方在栅栏位置交换数据

Exchanger 使用示例: public static void main(String[] args) {

Exchanger exchanger = new Exchanger();

ExchangerRunnable er1 = new ExchangerRunnable(exchanger,"1");

ExchangerRunnable er2 = new ExchangerRunnable(exchanger,"2");

new Thread(er1).start();

new Thread(er2).start();

}

class ExchangerRunnable implements Runnable{

private Exchanger e;

private Object o;

public ExchangerRunnable(Exchanger e, Object o) {

this.e = e;

this.o = o;

}

@Override

public void run() {

Object pre=o;

try {

o=e.exchange(o);

System.out.println("pre:"+pre+" now:"+o);

} catch (InterruptedException e1) {

e1.printStackTrace();

}

}

}

输出如下 pre:1 now:2

pre:2 now:1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值