Java面试总结(多线程包的使用)

CountDownLatch的用法

	 final CountDownLatch latch = new CountDownLatch(N);

		 for(int i=0;i<N;i++){ 
		    new Thread(new Runnable(){
		      
		      @Override
		      public void run(){
		    	  System.out.println("线程 "+Thread.currentThread().getName()+" 执行完毕");
		    	  //执行完一个线程则latch减一
		    	  latch.countDown();
		      }
		  
		    }).start();
		 }
				 
		//等到N减到0,也就说会等到N个线程都执行完
		latch.await();
				 
		System.out.println("所有线程都执行完毕,over!!!");

CyclicBarrier的用法

barrier.await():等到所有parties(线程)都调用

构造方法中的Runnable是当所有线程都执行await后才执行的。


		 int parties = 5;
		 final CyclicBarrier barrier = new CyclicBarrier(parties,new Runnable() {
			
			@Override
			public void run() {
				System.out.println("所有线程执行完毕");
			}
		});
		 
		 List<Thread> list = new ArrayList<Thread>();

		 for(int i=0;i<parties;i++){ 
			 Thread thread = new Thread(new Runnable(){
			      
			      @Override
			      public void run(){
			    	  System.out.println("线程 "+Thread.currentThread().getName()+" 准备执行");
			    	  try {
			    		//模拟执行完线程任务
						Thread.sleep(50);
						System.out.println("线程 "+Thread.currentThread().getName()+" 执行完毕");
						barrier.await();
					  } catch (InterruptedException | BrokenBarrierException  e) {
						e.printStackTrace();
					  }
			      }
			  
			    });
			 list.add(thread);
			 thread.start();
		 }
		 
		 //wait until done
		 for(Thread t:list){
			 t.join();
		 }
		 System.out.println("主线程继续做其他事情");
		 
	 

Semaphore

信号量是用来限制线程数量来访问一些(物理或者逻辑资源)

如果不释放许可,那么其他线程是无法获得许可的。

如下图,由于permits=10,那么只有10个线程能获得许可并执行,其他线程等待获得许可


		
		int permits = 10;
		
		final Semaphore semaphore = new Semaphore(permits);
		
		for(int i = 0; i < 100; i++){
			Thread thread = new Thread(new Runnable() {
				
				@Override
				public void run() {
					//获得许可
					try {
						semaphore.acquire();
						//模拟执行
						System.out.println(Thread.currentThread().getName() + " 获得许可,正在执行!!!");
						Thread.sleep(5000);
						//释放许可
						semaphore.release();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
			thread.start();
		}
	

Exchanger

例子一:按照官方例子稍微改动了一下,看不出效果


	
	
	public static void main(String[] args){
		Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
		DataBuffer emptyBuffer = null;
		DataBuffer fullBuffer = null;
		
		new Thread(new ReadBufferThread(exchanger, fullBuffer)).start();
		new Thread(new WriteToBufferThread(exchanger, emptyBuffer)).start();
	}
	
	//写入缓存数据
	static class WriteToBufferThread implements Runnable{

		Exchanger<DataBuffer> exchanger;
		DataBuffer emptyBuffer;
		
		public WriteToBufferThread(Exchanger<DataBuffer> exchanger,DataBuffer emptyBuffer) {
			this.exchanger = exchanger;
			this.emptyBuffer = emptyBuffer;
		}
		
		@Override
		public void run() {
			while(emptyBuffer != null){
				if(bufferIsFull(emptyBuffer)){
					try {
						//缓冲充满
						//通过exchanger将已满buffer传递过去并阻塞当前线程
						//另一个线程调用exchanger.exchange()时则完成了数据交换,此时buffer为空
						emptyBuffer = exchanger.exchange(emptyBuffer);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}else{
					addToBuffer(emptyBuffer);
				}
			}
		}
		
		//添加数据到buffer
		public void addToBuffer(DataBuffer buffer){
			
		}
		
		//判断buffer充满
		public boolean bufferIsFull(DataBuffer buffer){
			return true;
		}
		
	}
	
	//读取缓冲数据
	static class ReadBufferThread implements Runnable{
		Exchanger<DataBuffer> exchanger;
		DataBuffer fullBuffer;
		
		public ReadBufferThread(Exchanger<DataBuffer> exchanger,DataBuffer fullBuffer){
			this.exchanger = exchanger;
			this.fullBuffer = fullBuffer;
		}
		
		@Override
		public void run(){
			while(fullBuffer != null){
				takeFromBuffer(fullBuffer);
				if(bufferIsEmpty(fullBuffer)){
					try {
						fullBuffer = exchanger.exchange(fullBuffer);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
		public void takeFromBuffer(DataBuffer buffer){
			//to do
		}
		
		public boolean bufferIsEmpty(DataBuffer buffer){
			//to do
			return true;
		}
		
	}

例子二:自己简单写的一个例子,可以看到数据进行了交换


	
	
	public static void main(String[] args){
		Exchanger<String> exchanger = new Exchanger<String>();
		new ChangeThread1(exchanger).start();
		new ChangeThread2(exchanger).start();
	}
	
	static class ChangeThread1 extends Thread{
		Exchanger<String> exchanger;
		String myname = "ChangeThread1";
		
		public ChangeThread1(Exchanger<String> exchanger) {
			this.exchanger = exchanger;
		}
		
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName()+" this is ChangeThread 1 ");
			try {
				//名字进行了交换
				myname = exchanger.exchange(myname);
				System.out.println(Thread.currentThread().getName()+" "+myname);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}
	
	static class ChangeThread2 extends Thread{
		Exchanger<String> exchanger;
		String myname = "ChangeThread2";
		
		public ChangeThread2(Exchanger<String> exchanger) {
			this.exchanger = exchanger;
		}
		
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName()+ " this is ChangeThread 2 ");
			try {
				//名字进行了交换
				myname = exchanger.exchange(myname);
				System.out.println(Thread.currentThread().getName()+" "+myname);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}
	

控制台输出:

Thread-0 this is ChangeThread 1
Thread-1 this is ChangeThread 2
Thread-1 ChangeThread1
Thread-0 ChangeThread2

转载于:https://my.oschina.net/kyuan2cn/blog/1785510

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值