Java 多线程 (并发)总结
- - CSDN博客推荐文章《进程与线程的一个简单解释》 简单摘要如下. 电力有限,一次只能供给一个车间使用. 进程的内存是共享的,每个线程都能使用. 一个线程使用内存空间时,其他线程必须等它结束. 车间厕所,有人时其他人不能进入. 某内存空间,仅供固定数目线程使用. 挂N把锁,进入的人拿钥匙锁上,出来时放回. (1)Runnable接口 (通常选择这种,接口本身可以实现多重继承,比较灵活).
public class Main {
//等待2个子线程执行完毕,计数器为2
static CountDownLatch countDownLatch = new CountDownLatch(2);
public static void main(String[] args) {
System.out.println("start subThread doing...");
//创建并开启2个子线程
SubThread subThread1 = new SubThread();
SubThread subThread2 = new SubThread();
subThread1.start();
subThread2.start();
try {
//阻塞主线程,等待子线程结束
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("subThread are finish...");
}
static class SubThread extends Thread {
@Override
public void run() {
//模拟执行任务
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//子线程执行完毕,减少计数器
countDownLatch.countDown();
System.out.println(getName() + " done...");
}
}
} 运行结果:当Thread-1、Thread-0两个子线程执行完毕后,在运行main线程后续的逻辑 start subThread doing... Thread-1 done... Thread-0 done... subThread are finish...二、CyclicBarrier
public class Main {
//拦截2个子线程屏障
static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
public static void main(String[] args) {
System.out.println("start subThread doing...");
SubThread subThread1 = new SubThread();
SubThread subThread2 = new SubThread();
subThread1.start();
subThread2.start();
}
static class SubThread extends Thread {
@Override
public void run() {
try {
System.out.println(getName() + " doing first things.");
//模拟子线程执行第一个任务
sleep(3000);
System.out.println(getName() + " done first things.");
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
//完成第一个任务,告知达到屏障
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
//所有子线程都完成第一个任务后,继续运行每个子线程的下一个任务
System.out.println(getName() + " doing other things.");
}
}
} 运行结果:当子线程都执行完第一个任务到达屏障后,执行下一个任务 start subThread doing... Thread-0 doing first things. Thread-1 doing first things. Thread-1 done first things. Thread-0 done first things. Thread-0 doing other things. Thread-1 doing other things.三、Semaphore
public class Main {
//创建2个许可证
static Semaphore semaphore = new Semaphore(2);
public static void main(String[] args) {
System.out.println("start subThread doing...");
//同时开启4个子线程运行
for (int i = 0; i < 4; i++) {
SubThread subThread = new SubThread();
subThread.start();
}
}
static class SubThread extends Thread {
@Override
public void run() {
try {
//执行任务前获取许可证
semaphore.acquire();
System.out.println(getName() + "doing things.");
sleep(3000);
//执行完任务释放许可证
semaphore.release();
System.out.println(getName() + "finish things.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} 运行结果:同时只有2个线程运行,当某个线程运行完毕释放许可后,下一个线程才获取许可运行; start subThread doing... Thread-0doing things. Thread-1doing things. Thread-1finish things. Thread-2doing things. Thread-0finish things. Thread-3doing things. Thread-2finish things. Thread-3finish things.四、Exchanger
public class Main {
//用户线程间交换数据(String)对象exchanger
static Exchanger<String> exchanger = new Exchanger<>();
public static void main(String[] args) {
//创建2个子线程分别执行
SubThread1 subThread1 = new SubThread1();
SubThread2 subThread2 = new SubThread2();
subThread1.start();
subThread2.start();
}
static class SubThread1 extends Thread {
@Override
public void run() {
try {
System.out.println(getName() + "start doing...");
//模拟执行完成后,获取结果result1,并将result1交换给对方线程
sleep(3000);
String result1 = "3000";
String result2 = exchanger.exchange(result1);
//待两个线程都执行完毕后,交换数据进行比较
System.out.println(getName() + " thread1 result:" + result1 + " is equals thread2 result:" + result2 +
"," + result1.equals(result2));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class SubThread2 extends Thread {
@Override
public void run() {
try {
System.out.println(getName() + "start doing...");
//模拟执行完成后,获取结果result2,并将result2交换给对方线程
sleep(2000);
String result2 = "2000";
String result1 = exchanger.exchange(result2);
//待两个线程都执行完毕后,交换数据进行比较
System.out.println(getName() + " thread1 result:" + result1 + " is equals thread2 result:" + result2 +
"," + result1.equals(result2));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} 运行结果:线程1优先执行完毕,等待线程0执行完毕后,交换数据分别进行结果比较 Thread-1start doing... Thread-0start doing... Thread-1finish doing... Thread-0finish doing... Thread-0 thread1 result:3000 is equals thread2 result:2000,false Thread-1 thread1 result:3000 is equals thread2 result:2000,false