信号灯,,,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();
}
}