Semphore的主要作用是控制线程并发的数量
Exchanger可以使两个线程之间方便的进行通信
1.Semphore的使用
该类的主要作用是限制并发的数量,如果不限制并发数量,则cpu的资源很快被耗尽,cpu需要把时间片分给不同的线程对象,而且上下文切换也要消耗时间,最终造成系统运行效率降低,所以限制并发数量是很有必要的
1.1Semphore的同步性
构造参数,permits代表许可的意思,代表同一时间内,最多允许多少个线程执行acquire和release之间的代码
public class Service {
private Semaphore semaphore = new Semaphore(1);
public void testMethod() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()
+ " begin timer=" + System.currentTimeMillis());
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()
+ " end timer=" + System.currentTimeMillis());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadC extends Thread {
private Service service;
public ThreadC(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
ThreadB b = new ThreadB(service);
b.setName("B");
ThreadC c = new ThreadC(service);
c.setName("C");
a.start();
b.start();
c.start();
}
}
运行结果:
1.2Semphore类构造方法中参数permits的作用
修改上面的代码
public class Service {
private Semaphore semaphore = new Semaphore(2);
public void testMethod() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()
+ " begin timer=" + System.currentTimeMillis());
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()
+ " end timer=" + System.currentTimeMillis());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果;
A begin timer=1473079714988
B begin timer=1473079714988
B end timer=1473079719988
A end timer=1473079719988
C begin timer=1473079719988
C end timer=1473079724989
1.3acquire(int permits)参数作用以及动态添加permits许可数量
acquire(permits)每次调用一次该方法,就使用x个许可
一共有十个许可,每次执行acquire(2)代码消耗掉两个,所以同一时间只有5个线程执行acquire和release之间的代码
public class Service {
private Semaphore semaphore = new Semaphore(10);
public void testMethod() {
try {
semaphore.acquire(2);
System.out.println(Thread.currentThread().getName()
+ " begin timer=" + System.currentTimeMillis());
int sleepValue = ((int) (Math.random() * 10000));
System.out.println(Thread.currentThread().getName() + " 停止了"
+ (sleepValue / 1000) + "秒");
Thread.sleep(sleepValue);
System.out.println(Thread.currentThread().getName()
+ " end timer=" + System.currentTimeMillis());
semaphore.release(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA[] a = new ThreadA[10];
for (int i = 0; i < 10; i++) {
a[i] = new ThreadA(service);
a[i].start();
}
}
}
运行效果:
Thread-0 begin timer=1473080061065
Thread-0 停止了4秒
Thread-4 begin timer=1473080061067
Thread-4 停止了1秒
Thread-8 begin timer=1473080061067
Thread-8 停止了6秒
Thread-1 begin timer=1473080061067
Thread-1 停止了6秒
Thread-7 begin timer=1473080061067
Thread-7 停止了7秒
Thread-4 end timer=1473080062290
Thread-3 begin timer=1473080062290
Thread-3 停止了2秒
Thread-3 end timer=1473080064992
Thread-2 begin timer=1473080064992
Thread-2 停止了8秒
Thread-0 end timer=1473080065180
Thread-5 begin timer=1473080065180
Thread-5 停止了6秒
Thread-1 end timer=1473080068004
Thread-6 begin timer=1473080068004
Thread-6 停止了9秒
Thread-8 end timer=1473080068058
Thread-9 begin timer=1473080068058
Thread-9 停止了7秒
Thread-7 end timer=1473080068833
Thread-5 end timer=1473080071991
Thread-2 end timer=1473080073296
Thread-9 end timer=1473080075763
Thread-6 end timer=1473080077158
添加permits
public class Run {
public static void main(String[] args) {
try {
Semaphore semaphore = new Semaphore(5);
semaphore.acquire();
semaphore.acquire();
semaphore.acquire();
semaphore.acquire();
semaphore.acquire();
System.out.println(semaphore.availablePermits());
semaphore.release();
semaphore.release();
semaphore.release();
semaphore.release();
semaphore.release();
semaphore.release();
System.out.println(semaphore.availablePermits());
semaphore.release(4);
System.out.println(semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
0
6
10
1.4acquireUninterruptibly的使用
该方法的作用是:等待进入acquire的线程不允许被中断
public class Service {
private Semaphore semaphore = new Semaphore(1);
public void testMethod() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()
+ " begin timer=" + System.currentTimeMillis());
for (int i = 0; i < Integer.MAX_VALUE / 50; i++) {
String newString = new String();
Math.random();
}
System.out.println(Thread.currentThread().getName()
+ " end timer=" + System.currentTimeMillis());
semaphore.release();
} catch (InterruptedException e) {
System.out.println("线程" + Thread.currentThread().getName()
+ "进入了catch");
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
Thread.sleep(1000);
b.interrupt();
System.out.println("main中断了b");
}
}
运行结果:
A begin timer=1473080486599
线程B进入了catch
main中断了b
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
at java.util.concurrent.Semaphore.acquire(Unknown Source)
at service.Service.testMethod(Service.java:11)
at extthread.ThreadB.run(ThreadB.java:16)
A end timer=1473080487812
public class Service {
private Semaphore semaphore = new Semaphore(1);
public void testMethod() {
semaphore.acquireUninterruptibly();
System.out.println(Thread.currentThread().getName() + " begin timer="
+ System.currentTimeMillis());
for (int i = 0; i < Integer.MAX_VALUE / 50; i++) {
String newString = new String();
Math.random();
}
System.out.println(Thread.currentThread().getName() + " end timer="
+ System.currentTimeMillis());
semaphore.release();
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
Thread.sleep(1000);
b.interrupt();
System.out.println("main中断了b");
}
}
运行结果:
A begin timer=1473080684396
main中断了b
A end timer=1473080685591
B begin timer=1473080685591
B end timer=1473080686770
1.5 availablePermits,drainPermits方法
availablePermits获取当前可用的许可数
drainPermits获取并返回可用的许可数,并将可用许可置为0
public class MyService {
private Semaphore semaphore = new Semaphore(10);
public void testMethod() {
try {
semaphore.acquire();
System.out.println(semaphore.availablePermits());
System.out.println(semaphore.availablePermits());
System.out.println(semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
public class Run {
public static void main(String[] args) {
MyService service = new MyService();
service.testMethod();
}
}
运行结果:
9
9
9
public class MyService {
private Semaphore semaphore = new Semaphore(10);
public void testMethod() {
try {
semaphore.acquire();
System.out.println(semaphore.availablePermits());
System.out.println(semaphore.drainPermits() + " "
+ semaphore.availablePermits());
System.out.println(semaphore.drainPermits() + " "
+ semaphore.availablePermits());
System.out.println(semaphore.drainPermits() + " "
+ semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
public class Run {
public static void main(String[] args) {
MyService service = new MyService();
service.testMethod();
}
}
运行结果:
9
9 0
0 0
0 0
1.6 getQueueLength和hasQueuedThreads
getQueueLength获取等待许可的线程个数
hasQueuedThreads判断有没有线程在等待这个许可
public class MyService {
private Semaphore semaphore = new Semaphore(1);
public void testMethod() {
try {
semaphore.acquire();
Thread.sleep(1000);
System.out.println("还有大约" + semaphore.getQueueLength() + "个线程在等待");
System.out.println("是否有线程正在等待信号量呢?" + semaphore.hasQueuedThreads());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
public class MyThread extends Thread {
private MyService myService;
public MyThread(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
myService.testMethod();
}
}
public class Run {
public static void main(String[] args) {
MyService service = new MyService();
MyThread firstThread = new MyThread(service);
firstThread.start();
MyThread[] threadArray = new MyThread[4];
for (int i = 0; i < 4; i++) {
threadArray[i] = new MyThread(service);
threadArray[i].start();
}
}
}
运行结果:
还有大约4个线程在等待
是否有线程正在等待信号量呢?true
还有大约3个线程在等待
是否有线程正在等待信号量呢?true
还有大约2个线程在等待
是否有线程正在等待信号量呢?true
还有大约1个线程在等待
是否有线程正在等待信号量呢?true
还有大约0个线程在等待
是否有线程正在等待信号量呢?false
1.7 公平与非公平信号量测试
public class MyService {
private boolean isFair = true;
private Semaphore semaphore = new Semaphore(1, isFair);
public void testMethod() {
try {
semaphore.acquire();
System.out
.println("ThreadName=" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
public class MyThread extends Thread {
private MyService myService;
public MyThread(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
System.out.println("ThreadName=" + this.getName() + "启动了!");
myService.testMethod();
}
}
public class Run {
public static void main(String[] args) {
MyService service = new MyService();
MyThread firstThread = new MyThread(service);
firstThread.start();
MyThread[] threadArray = new MyThread[4];
for (int i = 0; i < 4; i++) {
threadArray[i] = new MyThread(service);
threadArray[i].start();
}
}
}
运行结果:
ThreadName=Thread-0启动了!
ThreadName=Thread-0
ThreadName=Thread-2启动了!
ThreadName=Thread-2
ThreadName=Thread-1启动了!
ThreadName=Thread-3启动了!
ThreadName=Thread-1
ThreadName=Thread-3
ThreadName=Thread-4启动了!
ThreadName=Thread-4
改为false运行结果:
ThreadName=Thread-0启动了!
ThreadName=Thread-1启动了!
ThreadName=Thread-1
ThreadName=Thread-2启动了!
ThreadName=Thread-2
ThreadName=Thread-0
ThreadName=Thread-3启动了!
ThreadName=Thread-3
ThreadName=Thread-4启动了!
ThreadName=Thread-4
1.8tryAcquire方法
尝试获取允许,如果获取不到返回false,此方法的特点是不阻塞
public class Service {
private Semaphore semaphore = new Semaphore(1);
public void testMethod() {
if (semaphore.tryAcquire()) {
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "首选进入!");
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String newString = new String();
Math.random();
}
semaphore.release();
} else {
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "未成功进入!");
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}
运行结果:
ThreadName=A首选进入!
ThreadName=B未成功进入!
1.9tryAcquire(permits)的用法
尝试获取x个允许,获取不到返回false
public class Service {
private Semaphore semaphore = new Semaphore(3);
public void testMethod() {
if (semaphore.tryAcquire(3)) {
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "首选进入!");
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String newString = new String();
Math.random();
}
// 方法release对应的permits值也要更改
semaphore.release(3);
} else {
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "未成功进入!");
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}
运行结果:
ThreadName=A首选进入!
ThreadName=B未成功进入!
1.10tryAcquire(timeout,timeunit)
在指定时间内获取到一个许可,如果获取不到返回false
public class Service {
private Semaphore semaphore = new Semaphore(1);
public void testMethod() {
try {
if (semaphore.tryAcquire(3, TimeUnit.SECONDS)) {
System.out.println("ThreadName="
+ Thread.currentThread().getName() + "首选进入!");
for (int i = 0; i < Integer.MAX_VALUE; i++) {
// String newString = new String();
// Math.random();
}
semaphore.release();
} else {
System.out.println("ThreadName="
+ Thread.currentThread().getName() + "未成功进入!");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}
运行结果:
ThreadName=A首选进入!
ThreadName=B首选进入!
打开注释运行结果:
ThreadName=A首选进入!
ThreadName=B未成功进入!
1.11 tryAcquire(permits,timeout,timeunit)
在指定时间内获取x个许可,获取不到返回false
public class Service {
private Semaphore semaphore = new Semaphore(3);
public void testMethod() {
// 1改成3
try {
if (semaphore.tryAcquire(3, 3, TimeUnit.SECONDS)) {
System.out.println("ThreadName="
+ Thread.currentThread().getName() + "首选进入!");
for (int i = 0; i < Integer.MAX_VALUE; i++) {
}
// 方法release对应的permits值也要更改
semaphore.release(3);
} else {
System.out.println("ThreadName="
+ Thread.currentThread().getName() + "未成功进入!");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}
运行结果:
ThreadName=B首选进入!
ThreadName=A首选进入!
1.12多进路-多处理-多出路实验
public class Service {
private Semaphore semaphore = new Semaphore(3);
public void sayHello() {
try {
semaphore.acquire();
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "准备");
System.out.println("begin hello " + System.currentTimeMillis());
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "打印"
+ (i + 1));
Thread.sleep(1000);
}
System.out.println(" end hello " + System.currentTimeMillis());
semaphore.release();
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread extends Thread {
private Service service;
public MyThread(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.sayHello();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
MyThread[] threadArray = new MyThread[6];
for (int i = 0; i < threadArray.length; i++) {
threadArray[i] = new MyThread(service);
threadArray[i].start();
}
}
}
运行结果:
ThreadName=Thread-1准备
begin hello 1473336081756
Thread-1打印1
ThreadName=Thread-2准备
begin hello 1473336081756
Thread-2打印1
ThreadName=Thread-0准备
begin hello 1473336081756
Thread-0打印1
Thread-2打印2
Thread-0打印2
Thread-1打印2
Thread-2打印3
Thread-1打印3
Thread-0打印3
end hello 1473336084774
end hello 1473336084774
ThreadName=Thread-1结束
end hello 1473336084774
ThreadName=Thread-3准备
ThreadName=Thread-4准备
begin hello 1473336084774
Thread-4打印1
ThreadName=Thread-5准备
begin hello 1473336084774
Thread-5打印1
ThreadName=Thread-0结束
begin hello 1473336084774
Thread-3打印1
ThreadName=Thread-2结束
Thread-3打印2
Thread-4打印2
Thread-5打印2
Thread-3打印3
Thread-5打印3
Thread-4打印3
end hello 1473336087785
ThreadName=Thread-5结束
end hello 1473336087785
ThreadName=Thread-4结束
end hello 1473336087785
ThreadName=Thread-3结束
1.13多进路-单处理-多出路实验
public class Service {
private Semaphore semaphore = new Semaphore(3);
private ReentrantLock lock = new ReentrantLock();
public void sayHello() {
try {
semaphore.acquire();
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "准备");
lock.lock();
System.out.println("begin hello " + System.currentTimeMillis());
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "打印"
+ (i + 1));
Thread.sleep(1000);
}
System.out.println(Thread.currentThread().getName()+" end hello ");
lock.unlock();
semaphore.release();
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread extends Thread {
private Service service;
public MyThread(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.sayHello();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
MyThread[] threadArray = new MyThread[6];
for (int i = 0; i < threadArray.length; i++) {
threadArray[i] = new MyThread(service);
threadArray[i].start();
}
}
}
ThreadName=Thread-0准备
begin hello 1473336405058
Thread-0打印1
ThreadName=Thread-2准备
ThreadName=Thread-1准备
Thread-0打印2
Thread-0打印3
Thread-0 end hello
begin hello 1473336408060
Thread-2打印1
ThreadName=Thread-3准备
ThreadName=Thread-0结束
Thread-2打印2
Thread-2打印3
Thread-2 end hello
ThreadName=Thread-2结束
begin hello 1473336411070
Thread-1打印1
ThreadName=Thread-4准备
Thread-1打印2
Thread-1打印3
Thread-1 end hello
ThreadName=Thread-5准备
begin hello 1473336414074
ThreadName=Thread-1结束
Thread-3打印1
Thread-3打印2
Thread-3打印3
Thread-3 end hello
ThreadName=Thread-3结束
begin hello 1473336417077
Thread-4打印1
Thread-4打印2
Thread-4打印3
Thread-4 end hello
ThreadName=Thread-4结束
begin hello 1473336420089
Thread-5打印1
Thread-5打印2
Thread-5打印3
Thread-5 end hello
ThreadName=Thread-5结束
1.14使用Semphore创建字符串池
public class ListPool {
private int poolMaxSize = 5;
private int semaphorePermits = 5;
private List list = new ArrayList();
private Semaphore concurrencySemaphore = new Semaphore(semaphorePermits);
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public ListPool() {
super();
for (int i = 0; i < poolMaxSize; i++) {
list.add("高洪岩" + (i + 1));
}
}
public String get() {
String getString = null;
try {
concurrencySemaphore.acquire();
lock.lock();
while (list.size() == 0) {
condition.await();
}
getString = list.remove(0);
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
return getString;
}
public void put(String stringValue) {
lock.lock();
list.add(stringValue);
condition.signalAll();
lock.unlock();
concurrencySemaphore.release();
}
}
public class MyThread extends Thread {
private ListPool listPool;
public MyThread(ListPool listPool) {
super();
this.listPool = listPool;
}
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String getString = listPool.get();
System.out.println(Thread.currentThread().getName() + " 取得值 "
+ getString);
listPool.put(getString);
}
}
}
public class Run {
public static void main(String[] args) {
ListPool pool = new ListPool();
MyThread[] threadArray = new MyThread[12];
for (int i = 0; i < threadArray.length; i++) {
threadArray[i] = new MyThread(pool);
}
for (int i = 0; i < threadArray.length; i++) {
threadArray[i].start();
}
}
}
运行结果:
1.15使用Semphore实现生产者消费者模式
public class RepastService {
volatile private Semaphore setSemaphore = new Semaphore(10);// 厨师
volatile private Semaphore getSemaphore = new Semaphore(20);// 就餐者
volatile private ReentrantLock lock = new ReentrantLock();
volatile private Condition setCondition = lock.newCondition();
volatile private Condition getCondition = lock.newCondition();
volatile private Object[] producePosition = new Object[4];
private boolean isEmpty() {
boolean isEmpty = true;
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] != null) {
isEmpty = false;
break;
}
}
if (isEmpty == true) {
return true;
} else {
return false;
}
}
private boolean isFull() {
boolean isFull = true;
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] == null) {
isFull = false;
break;
}
}
return isFull;
}
public void set() {
try {
// System.out.println("set");
setSemaphore.acquire();// 允许同时最多有10个厨师进行生产
lock.lock();
while (isFull()) {
// System.out.println("生产者在等待");
setCondition.await();
}
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] == null) {
producePosition[i] = "数据";
System.out.println(Thread.currentThread().getName()
+ " 生产了 " + producePosition[i]);
break;
}
}
getCondition.signalAll();
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
setSemaphore.release();
}
}
public void get() {
try {
// System.out.println("get");
getSemaphore.acquire();// 允许同时最多有16个就餐者
lock.lock();
while (isEmpty()) {
// System.out.println("消费者在等待");
getCondition.await();
}
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] != null) {
System.out.println(Thread.currentThread().getName()
+ " 消费了 " + producePosition[i]);
producePosition[i] = null;
break;
}
}
setCondition.signalAll();
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
getSemaphore.release();
}
}
}
public class ThreadP extends Thread {
private RepastService service;
public ThreadP(RepastService service) {
super();
this.service = service;
}
@Override
public void run() {
service.set();
}
}
public class ThreadC extends Thread {
private RepastService service;
public ThreadC(RepastService service) {
super();
this.service = service;
}
@Override
public void run() {
service.get();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
RepastService service = new RepastService();
ThreadP[] arrayP = new ThreadP[60];
ThreadC[] arrayC = new ThreadC[60];
for (int i = 0; i < 60; i++) {
arrayP[i] = new ThreadP(service);
arrayC[i] = new ThreadC(service);
}
Thread.sleep(2000);
for (int i = 0; i < 60; i++) {
arrayP[i].start();
arrayC[i].start();
}
}
}
2.Exchanger的使用
两个线程之间传输数据,比wait/notify更方便
2.1exchange方法阻塞的特性
exchange方法调用后等待其他线程来取得数据,如果没有其他线程来取数据,就一直阻塞等待
public class ThreadA extends Thread {
private Exchanger exchanger;
public ThreadA(Exchanger exchanger) {
super();
this.exchanger = exchanger;
}
@Override
public void run() {
try {
System.out.println("在线程A中得到线程B的值=" + exchanger.exchange("中国人A"));
System.out.println("A end!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
Exchanger exchanger = new Exchanger();
ThreadA a = new ThreadA(exchanger);
a.start();
System.out.println("main end!");
}
}
运行结果:A线程一直等待
main end!
2.2方法exchange()传递数据
public class ThreadA extends Thread {
private Exchanger exchanger;
public ThreadA(Exchanger exchanger) {
super();
this.exchanger = exchanger;
}
@Override
public void run() {
try {
System.out.println("在线程A中得到线程B的值=" + exchanger.exchange("中国人A"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadB extends Thread {
private Exchanger exchanger;
public ThreadB(Exchanger exchanger) {
super();
this.exchanger = exchanger;
}
@Override
public void run() {
try {
System.out.println("在线程B中得到线程A的值=" + exchanger.exchange("中国人B"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
Exchanger exchanger = new Exchanger();
ThreadA a = new ThreadA(exchanger);
ThreadB b = new ThreadB(exchanger);
a.start();
b.start();
}
}
运行结果:
在线程B中得到线程A的值=中国人A
在线程A中得到线程B的值=中国人B
2.3exchange(data,timeout,timeuit);
指定时间内没有线程来获取数据就抛异常
public class ThreadA extends Thread {
private Exchanger exchanger;
public ThreadA(Exchanger exchanger) {
super();
this.exchanger = exchanger;
}
@Override
public void run() {
try {
System.out.println("在线程A中得到线程B的值="
+ exchanger.exchange("中国人A", 5, TimeUnit.SECONDS));
System.out.println("A end!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
Exchanger exchanger = new Exchanger();
ThreadA a = new ThreadA(exchanger);
a.start();
System.out.println("main end!");
}
}
运行结果:
main end!
java.util.concurrent.TimeoutException
at java.util.concurrent.Exchanger.exchange(Unknown Source)
at extthread.ThreadA.run(ThreadA.java:20)