Java - Semaphore 与 Exchanger

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/PeersLee/article/details/79894560

Semaphore 

  • 控制线程并发数量。
  • 内部维护一个等待队列,acquire 使配额减1,release 使配额加1。
package Chapter01;

import java.util.concurrent.Semaphore;

public class _01_Run {
	/*
	 * 多进路-多处理:
	 * 等待队列中的线程同时,处理任务
	 */
	public static void main(String[] args) {
		Service s = new Service();
		MyThread []threads = new MyThread[12];
		for (int i = 0; i < threads.length; i++) {
			threads[i] = new MyThread(s);
			threads[i].start();
		}
	}
	
	static class Service {
		private Semaphore s = new Semaphore(3);
		void say() {
			try {
				s.acquire();
				System.out.println("ThreadName = "+ Thread.currentThread().getName()+
						" 准备中");
				System.out.println("Begin "+ System.currentTimeMillis());
				for (int i = 0; i < 5; i++) {
					System.out.println(Thread.currentThread().getName()+ 
							" 打印  "+ (i+1));
				}
				System.out.println("End " + System.currentTimeMillis());
				s.release();
				System.out.println("ThreadName = "+ Thread.currentThread().getName()+
						"结束");
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
	
	static class MyThread extends Thread {
		private Service s;
		
		public MyThread(Service s) {
			super();
			this.s = s;
		}
		
		@Override
		public void run() {
			s.say();
		}
	}
}




package Chapter01;

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;

public class _02_Run {
	/*
	 * 多进路-单处理:
	 * 等待队列中的线程,按照顺序(阻塞)执行任务
	 */
	public static void main(String[] args) {
		Service s = new Service();
		MyThread []threads = new MyThread[12];
		for (int i = 0; i < threads.length; i++) {
			threads[i] = new MyThread(s);
			threads[i].start();
		}
	}
	
	static class Service {
		private Semaphore s = new Semaphore(3);
		private ReentrantLock lock = new ReentrantLock();
		
		void say() {
			try {
				s.acquire();
				System.out.println("ThreadName = "+ Thread.currentThread().getName()+
						" 准备中");
				lock.lock();
				System.out.println("Begin "+ System.currentTimeMillis());
				for (int i = 0; i < 5; i++) {
					System.out.println(Thread.currentThread().getName()+ 
							" 打印  "+ (i+1));
				}
				System.out.println("End " + System.currentTimeMillis());
				lock.unlock();
				s.release();
				System.out.println("ThreadName = "+ Thread.currentThread().getName()+
						"结束");
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
	
	static class MyThread extends Thread {
		private Service s;
		
		public MyThread(Service s) {
			super();
			this.s = s;
		}
		
		@Override
		public void run() {
			s.say();
		}
	}
}




Exchanger

  • 线程间交换数据。
  • 第一个线程先exchanger,然后等待领一个线程执行exchanger,然后二者交换数据。

package Chapter01;

import java.util.concurrent.Exchanger;

public class _03_Run {
	/*
	 * exchange():
	 * 1. 线程A 会阻塞
	 * 2. 交换数据
	 */
	public static void main(String[] args) {
		Exchanger<String> e = new Exchanger<String>();
		ThreadA a = new ThreadA(e);
		ThreadB b = new ThreadB(e);
		a.start();
		b.start();
	}
	
	static class ThreadA extends Thread {
		private Exchanger<String> e;
		
		public ThreadA(Exchanger<String> e) {
			super();
			this.e = e;
		}
		
		@Override
		public void run() {
			try {
				System.out.println("A 中得到B 的值:" + e.exchange("a"));
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
	
	static class ThreadB extends Thread {
		private Exchanger<String> e;
		
		public ThreadB(Exchanger<String> e) {
			super();
			this.e = e;
		}
		
		@Override
		public void run() {
			try {
				System.out.println("B 中得到A 的值:" + e.exchange("b"));
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
}




推荐书目:《Java 编发编程 核心方法与框架》

猜你喜欢

转载自blog.csdn.net/PeersLee/article/details/79894560