java5线程并发库中的工具

本文深入探讨了并发编程中的关键概念,包括信号量、栅栏和计数器的使用场景及实现原理。通过实例代码展示了如何利用这些工具解决多线程同步问题,确保程序的正确性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

信号灯,,,Semaphore类。。它所实现的功能就类似于公共厕所,,如果有10个人同时要去上这个厕所,而厕所只有5个坑,所以一次只能进去5个人,当5个人中的任何一个离开后,其中另外等待的5个人中的1个人就可以上了!!!

如果说Semaphore类中只维护一个坑,就和synchronized互斥相似了。。。但是它比单纯的互斥要好,,它还能够恢复死锁状态。。。

 

Semaphore类中的acquire方法获得一个信号的许可!!!release方法释放一个信号的许可!!!而这两个方法可以被两个不同的线程调用。。。。

package concurrent.utils;  
  
import java.util.Random;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Semaphore;  
  
  
public class SemaphoreTest {  
    public static void main(String[] args) {  
        ExecutorService service = Executors.newFixedThreadPool(10);  
        final Semaphore post = new Semaphore(5);  
        for (int i = 0; i < 10; i++) {  
            service.execute(new Runnable(){  
                public void run(){  
                    try {  
                        post.acquire();  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                      
                    System.out.println(Thread.currentThread().getName()  
                            +"线程已进入厕所开始便便,," +"当前厕所有:"+  
                            (5-post.availablePermits())+"人在便便!!");  
                      
                    try {  
                        Thread.sleep(new Random().nextInt(1000));  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                    System.out.println(Thread.currentThread().getName()  
                            +"擦完屁股冲了水,,即将离开!!");  
                    post.release();  
                    System.out.println(Thread.currentThread().getName()  
                            +"已经离开,当前厕所有:"+(5-post.availablePermits())+"人在便便!!");  
                }  
            });  
        }  
    }  
} 

 

 

栅栏,,CyclicBarrier,,,多个同样任务线程的线程中的一道栅栏,,,等待其他线程都执行到此,才开始一起向下执行!!!!

package concurrent.utils;

import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicBarrierTest {
	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final CyclicBarrier barrier = new CyclicBarrier(3);
		for (int i = 0; i < 3; i++) {
			service.execute(new Runnable() {
				@Override
				public void run() {
					try {
						System.out.println(Thread.currentThread().getName()
								+ "已到达目的地一!!当前已有"
								+ (barrier.getNumberWaiting() + 1) + "已经到达,"
								+ (barrier.getNumberWaiting()==2?"人到齊了继续出发!":"开始等待!"));

						barrier.await();
						Thread.sleep(new Random().nextInt(1000));
						System.out.println(Thread.currentThread().getName()
								+ "已到达目的地二!!当前已有"
								+ (barrier.getNumberWaiting() + 1) + "已经到达"
								+ (barrier.getNumberWaiting()==2?"人到齊了继续出发!":"开始等待!"));

						barrier.await();
						Thread.sleep(new Random().nextInt(1000));
						System.out.println(Thread.currentThread().getName()
								+ "已到达目的地三!!当前已有"
								+ (barrier.getNumberWaiting() + 1) + "已经到达"
								+ (barrier.getNumberWaiting()==2?"旅途結束,愉快解散!":"开始等待!"));
						barrier.await();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		}
	}
}

 

CountDownLatch,,,相当于一个计数器!!!可以实现线程的计数,,互相之间,,,到达某个数量,再往下执行!

package concurrent.utils;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchTest {
	public static void main(String[] args) {
		ExecutorService pool = Executors.newFixedThreadPool(3);
		final CountDownLatch order = new CountDownLatch(1);
		final CountDownLatch answer = new CountDownLatch(3);
		for (int i = 0; i < 3; i++) {
			pool.execute(new Runnable(){
				public void run(){
					try {
						System.out.println(Thread.currentThread().getName()+
								"开始等待主线程命令!");
						Thread.sleep(new Random().nextInt(1000));
						order.await();
						System.out.println(Thread.currentThread().getName()+
								"接受开始命令,开始运行!");
						Thread.sleep(new Random().nextInt(1000));
						answer.countDown();
						System.out.println(Thread.currentThread().getName()+
								"运行完毕,向主线程发送运行结果!");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		}
		try {
			Thread.sleep(new Random().nextInt(1000));
			System.out.println(Thread.currentThread().getName()+
			"开始发送开始命令!");
			order.countDown();
			Thread.sleep(new Random().nextInt(1000));
			answer.await();
			System.out.println(Thread.currentThread().getName()+
					"所有线程运行结果接受完毕,准备退出!!");
		} catch (Exception e) {
			e.printStackTrace();
		}
		pool.shutdown();
	}
}
 

Exchanger,,,实现两个线程之间的数据交换!!!通过exchange方法,提交数据,,,返回值为交换后得到的数据!!!

就像两个情报员互相交换数据一样,,其中一个到了,,另一个没到,,到的那个就会开始等待,等待没到的到了就进行交换。。。

package concurrent.utils;

import java.util.concurrent.Exchanger;

public class ExChangerTest {
	public static void main(String[] args) {
		final Exchanger<String> exchanger = new Exchanger<String>();
		
		new Thread(){
			public void run(){
				String data1 = "firstdata";
				System.out.println(Thread.currentThread().getName()+
						"拿着数据:"+data1+",开始准备交换数据!");
				try {
					Thread.sleep(10000);
					String data2 = exchanger.exchange(data1);
					System.out.println("交换数据成功!!");
					System.out.println(Thread.currentThread().getName()+
							"获得数据:"+data2);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}		
			}
		}.start();
		new Thread(){
			public void run(){
				String data1 = "seconddata";
				System.out.println(Thread.currentThread().getName()+
						"拿着数据:"+data1+",开始准备交换数据!");
				try {
					Thread.sleep(10000);
					String data2 = exchanger.exchange(data1);
					System.out.println("交换数据成功!!");
					System.out.println(Thread.currentThread().getName()+
							"获得数据:"+data2);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值