文档章节

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

 空无一长物
发布于 2018/03/27 11:30
字数 771
阅读 712
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

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

粉丝 2
博文 67
码字总数 27922
作品 0
深圳
私信 提问
加载中
请先登录后再评论。
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.5K
6
Flappy Bird(安卓版)逆向分析(一)

更改每过一关的增长分数 反编译的步骤就不介绍了,我们直接来看反编译得到的文件夹 方法1:在smali目录下,我们看到org/andengine/,可以知晓游戏是由andengine引擎开发的。打开/res/raw/at...

enimey
2014/03/04
6K
18
浅入浅出Android(003):使用TextView类构造文本控件

基础: TextView是无法供编辑的。 当我们新建一个项目MyTextView时候,默认的布局(/res/layout/activity_main.xml)中已经有了一个TextView: <TextView 运行效果如下: 修改其文本内容...

樂天
2014/03/22
642
1
CDH5: 使用parcels配置lzo

一、Parcel 部署步骤 1 下载: 首先需要下载 Parcel。下载完成后,Parcel 将驻留在 Cloudera Manager 主机的本地目录中。 2 分配: Parcel 下载后,将分配到群集中的所有主机上并解压缩。 3 激...

cloud-coder
2014/07/01
6.8K
1
Swift百万线程攻破单例(Singleton)模式

一、不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法。单例的实现有多种方法,如下面: class SwiftSingleton { } 这段代码的实现,在shared中进行条...

一叶博客
2014/06/20
3.4K
16

没有更多内容

加载失败,请刷新页面

加载更多

如何在Pandas的DataFrame中的行上进行迭代? - How to iterate over rows in a DataFrame in Pandas?

问题: I have a DataFrame from pandas: 我有一个来自熊猫的DataFrame : import pandas as pdinp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}]df = pd.DataFrame(......

富含淀粉
44分钟前
20
0
与电商节伴生,平台销量榜单背后还有被低估的营销价值

文 | 曾响铃 来源 | 科技向令说(xiangling0815) 时至今日,电商节已经成为各巨头零售平台例行的活动,花样在不断创新,玩法也在不断涌现。 在这个过程中,伴随电商节的各种品牌、产品销量榜...

曾响铃
46分钟前
22
0
volatile关键字详解

前言 提到JAVA的并发编程,就不得不提volatile关键字,不管是在面试还是实际开发中,volatile关键字的使用都是一个应该掌握的技能。它之所以重要,是因为它和JAVA并发编程中会遇到三种重要问...

ls_cherish
今天
15
0
比继承更偏爱组成? - Prefer composition over inheritance?

问题: Why prefer composition over inheritance? 为什么更喜欢使用组合而不是继承? What trade-offs are there for each approach? 每种方法都有哪些取舍? When should you choose inher...

javail
今天
26
0
2020软件测试工程师史上最全面试题(内含答案)-看完BATJ面试官对你竖起大拇指!

以下是软件测试相关的面试题及答案,欢迎大家参考! 我不是至尊宝,也不是孙悟空,我只是那城墙下的一猿。  1、你的测试职业发展是什么?  测试经验越多,测试能力越高。所以我的职业发展是需...

程序员一凡
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部