在这里插入代码片
### 一 线程的创建方式
1 继承Thread类
Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行 run()方法。
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("run");
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
2 实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("runnable");
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
CountDownLatch
/**
* @Author: wang-peng
* @Date: 2020/7/9 18:04
* 线程计数器
* CountDownLatch(int count) 构造一个以给定计数 CountDownLatch CountDownLatch。
* countDownLatch.countDown(); 执行一个线程,总数减一
* countDownLatch.await(); 线程等待,所有线程执行完成,继续一下操作。
* CountDownLatch会阻塞主线程,
* 计数器只能使用一次
*/
public class CountDownLatchTest {
public static void main(String[] args)throws Exception {
final CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i=0;i<10;i++){
new Thread(){
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"开始");
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程"+Thread.currentThread().getName()+"完毕");
countDownLatch.countDown();
};
}.start();
}
System.out.println("线程allStart");
countDownLatch.await();
// CountDownLatch会阻塞主线程,
System.out.println("线程结束");
}
}
CyclicBarrier
/**
* @Author: wang-peng
* @Date: 2020/7/15 15:06
* 回环栅栏 循环屏障
* await() 建立一个屏障,等待所有线程到这个状态后,继续执行
* CyclicBarrier不会阻塞主线程,只会阻塞子线程。
* CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,
* 比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次
*
* public CyclicBarrier(int parties);//parties表示屏障拦截的线程数量
* public CyclicBarrier(int parties, Runnable barrierAction);//parties表示屏障拦截的线程数量,在线程到达屏障时,优先执行barrierAction
*/
public class CyclicBarrierTest {
public static void main(String[] args)throws Exception {
final CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.out.println("--执行barrierAction----");
}
});
for (int i = 0; i < 5; i++) {
new Thread() {
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName() + "开始");
try {
//执行业务写入数据
Thread.sleep(2000L);
// CyclicBarrier不会阻塞主线程,只会阻塞子线程。
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
//所有线程到达屏障之后(执行barrierAction)再执行后续操作
System.out.println("线程" + Thread.currentThread().getName() + "完毕");
}
}.start();
}
//线程以外继续执行 CyclicBarrier不会阻塞主线程,只会阻塞子线程。
System.out.println("线程allStart");
System.out.println("线程结束");
}
}
Semaphore
/**
* @Author: wang-peng
* @Date: 2020/7/15 16:02
* 计数信号量
* 控制线程执行数量,
* 和锁有些类似,必须拿到信号许可acquire(),才能执行
* 主线程不阻塞
*/
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3,true);
for (int i=0;i<5;i++){
new Thread(){
@Override
public void run() {
try {
//semaphore.acquire(); //阻塞线程
if (semaphore.tryAcquire()){ //获取成功,返回true,失败返回false
System.out.println("-----线程--"+Thread.currentThread().getName()+"---start--");
Thread.sleep(2000L);
System.out.println("-----线程--"+Thread.currentThread().getName()+"---end--");
semaphore.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
//主线程不阻塞
System.out.println("-----主线程---start--");
}
}
LockSupport
park();阻塞线程 , 在没有获取许可之前阻塞。
unpark();解除线程阻塞, 获取一个许可,之后阻塞的线程直接执行。
public class T13_TestLockSupport {
public static void main(String[] args) {
Thread t = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(i);
if(i == 5) {
LockSupport.park();
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
LockSupport.unpark(t);
System.out.println(1111);
}
}