****1. Object 的 wait,notify,notifyAll
/**
* 使用object的wait方法和notify方法以及notifyAll 方法必须依赖于synchronized 关键字的方法或代码块
*/
public class WaitThread {
private int i=0;
private Object object = new Object();
/**
* 奇数打印(里面描述内容同理使用于even()方法)
*/
public void odd(){
while (i<10){
//打印奇数
synchronized (object){
if (i%2==1){
System.out.println("奇数"+i);
i++;
//打印结束后通知其它当前锁对象线程执行
//object.notify(); 此处是奇偶方法抢锁用了notify()方法,但一般使用notifyAll()方法更稳妥
object.notify();
}else {
try {
//如果不是奇数就进入等待状态释放锁让其他线程获取锁执行
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 偶数打印
*/
public void even(){
while (i<10){
//打偶数
synchronized (object){
if (i%2==0){
System.out.println("偶数"+i);
i++;
object.notify();
}else {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
final WaitThread threads = new WaitThread();
//开启奇数线程打印
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
threads.odd();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
threads.even();
}
});
thread1.start();
thread2.start();
}
}
2. Condition 的 await,signal ,signalAll**
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionDemo {
private int i=0;
/**
* 这是手动锁类似synchronized 但比较灵活
*/
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
/**
* 奇数打印
*/
public void odd(){
while (i<10){
//打印奇数
//lock 加锁和解锁是手动的所以必须 是 lock.lock() 和 lock.unlock();成对出现不然容易造成死锁
lock.lock();
try {
if (i%2==1){
System.out.println("奇数"+i);
i++;
//唤醒另一个线程 signal 类似上面的 notify方法
condition.signal();
}else {
try {
//await 类似上面的wait 方法 描述不在赘述
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}finally {
lock.unlock();
}
}
}
/**
* 偶数打印
*/
public void even(){
while (i<10){
//打偶数
lock.lock();
try{
if (i%2==0){
System.out.println("偶数"+i);
i++;
condition.signal();
}else {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
final WaitThread threads = new WaitThread();
//开启奇数线程打印
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
threads.odd();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
threads.even();
}
});
thread1.start();
thread2.start();
}
3. CountDownLatch : 用于某个线程A等待若干个其他线程执行完之后,它才执行
import java.util.concurrent.CountDownLatch;
/**
* countDownLatch某个线程等待其他线程完毕后,它在执行
*/
public class CountDownLatchDemo {
private CountDownLatch countDownLatch = new CountDownLatch(3);
/**
* 运动员准备方法
*/
public void player(){
//1.获取线程运动员名称
String name = Thread.currentThread().getName();
//2.运动员准备
System.out.println("运动员:"+name+"正在准备中!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//3.运动员准备完毕已就绪
System.out.println("运动员:"+name+"准备完毕已就绪!");
//每个运动员准备就绪后就 -- 即:countDownLatch.countDown()
countDownLatch.countDown();
}
/**
* 教练员方法
*/
public void coach(){
//1.获取教练员名称
String name = Thread.currentThread().getName();
//2.教练员等待运动员准备
System.out.println("教练员:"+name+"等地运动员准备");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("教练员:"+name+"开始训练");
}
public static void main(String[] args) {
final CountDownLatchDemo countDownLatchDemo = new CountDownLatchDemo();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
countDownLatchDemo.player();
}
},"运动员一号");
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
countDownLatchDemo.player();
}
},"运动员二号");
Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
countDownLatchDemo.player();
}
},"运动员三号");
Thread thread5 = new Thread(new Runnable() {
@Override
public void run() {
countDownLatchDemo.coach();
}
},"教练陈");
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}
4. CyclicBarrier: 一组线程等待某个状态之后再全部同时执行
import java.util.Date;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class ThreeThreadStart {
private CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
public void startThread(){
//1.打印新准备启动
String name = Thread.currentThread().getName();
System.out.println(name+"正在准备。。。");
//2.调用CyclicBarrier 的方法await方法等线程全部准备完成
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
//3.打印线程启动完毕
System.out.println(name+"已经启动完毕:"+new Date().getTime());
}
public static void main(String[] args) {
ThreeThreadStart starts = new ThreeThreadStart();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
starts.startThread();
}
},"线程1");
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
starts.startThread();
}
},"线程2");
Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
starts.startThread();
}
},"线程3");
thread2.start();
thread3.start();
thread4.start();
}
}
5. Semaphore: 用于控制对某组资源的访问权限**
import java.util.concurrent.Semaphore;
public class SemaphoreDemo {
static class Work implements Runnable{
private int workNum ;// 工人工号
[Semaphore 具体用法参考]
(https://blog.csdn.net/carson0408/article/details/79475723)
private Semaphore semaphore; //机器数
public Work(int workNum, Semaphore semaphore) {
this.workNum = workNum;
this.semaphore = semaphore;
}
@Override
public void run() {
//1.工人获取机器
try {
semaphore.acquire();
//2.打印线程,获取机器,开始工作
String name = Thread.currentThread().getName();
System.out.println(name+"获取到机器,开始工作。。。。");
//3.机器睡眠,模拟人工使用
Thread.sleep(1000);
//4.使用完毕,释放机器
semaphore.release();
System.out.println(name+"工人使用完毕,可以供其他工人使用");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int workers = 8;
Semaphore semaphore = new Semaphore(3);
for (int i=0;i<workers;i++){
new Thread(new Work(i,semaphore)).start();
}
}
}