文章目录
-
- 并发编程
-
- Thread
-
- sleep、yield、join
- [daemon (守护线程)](#daemon (守护线程))
- 锁
-
- [[synchronized ](https://blog.csdn.net/EnjoyFight/article/details/127457876)](#synchronized )
- 线程池
jdk目录结构
jdk1.8
jdk20
函数式接口
https://blog.csdn.net/Don_t_always_ail/article/details/132222951
wait、notify、notifyAll
java
package com.example.demo4.jdk;
import java.util.UUID;
public class WaitTest {
public static void main(String[] args) {
Print print = new Print();
new Thread(() -> {
for (int i = 0; i < 28; i++) {
print.printNum();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 26; i++) {
print.printChar();
}
}).start();
}
}
class Print{
private int flag = 1;
private int count = 1;
public synchronized void printNum(){
if(flag == 2 && count < 27){
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print(2*count-1);
System.out.print(2*count);
flag = 2;
if(count < 27){
notify();
}
}
public synchronized void printChar(){
if(flag == 1){
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println((char)(count - 1 + 'A'));
flag = 1;
count++;
notify();
// notifyAll();
}
}
并发编程
- 可见性:synchronized
- 有序性
- 原子性
Thread
线程状态
线程状态。 线程可以处于以下状态之一:
- NEW
尚未启动的线程处于此状态。 - RUNNABLE
在Java虚拟机中执行的线程处于此状态。 - BLOCKED
被阻塞等待监视器锁定的线程处于此状态。 - WAITING
正在等待另一个线程执行特定动作的线程处于此状态。 - TIMED_WAITING
正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。 - TERMINATED
已退出的线程处于此状态。
sleep、yield、join
-
sleep(long millis) :使当前正在执行的线程停留(暂停执行)指定的毫秒数,这取决于系统定时器和调度程序的精度和准确性。
-
sleep(long millis, int nanos) :导致正在执行的线程以指定的毫秒数加上指定的纳秒数来暂停(临时停止执行),这取决于系统定时器和调度器的精度和准确性。
-
yield() :对调度程序的一个暗示,即当前线程愿意产生当前使用的处理器。
-
join() :等待这个线程死亡。
-
void join(long millis) :等待这个线程死亡 millis毫秒。
java
package com.example.demo4.thread;
public class JoinTest implements Runnable {
private String name;
public JoinTest(String name){
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + i);
}
}
public static void main(String[] args) {
JoinTest joinTest = new JoinTest("vip线程:");
Thread thread1 = new Thread(joinTest);
thread1.start();
for (int i = 0; i < 50; i++) {
if(i == 40){
try {
thread1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("主线程:" + i);
}
}
}
daemon (守护线程)
- 此线程标记为daemon线程或用户线程。 当运行的唯一线程都是守护进程线程时,Java虚拟机将退出。
- 线程启动前必须调用此方法。
锁
synchronized
线程池
java
package com.example.demo4.thread;
import org.junit.jupiter.api.Test;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.*;
public class ThreadPoolSizeTest {
@Test
public void test() throws InterruptedException {
new HashMap<>();
ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 3, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardPolicy());
//每隔两秒打印线程池的信息
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(() -> {
System.out.println("=====================================thread-pool-info:" + new Date() + "=====================================");
System.out.println("CorePoolSize:" + executorService.getCorePoolSize());
System.out.println("PoolSize:" + executorService.getPoolSize());
System.out.println("ActiveCount:" + executorService.getActiveCount());
System.out.println("KeepAliveTime:" + executorService.getKeepAliveTime(TimeUnit.SECONDS));
System.out.println("QueueSize:" + executorService.getQueue().size());
}, 0, 2, TimeUnit.SECONDS);
try {
//同时提交5个任务,模拟达到最大线程数
for (int i = 0; i < 5; i++) {
executorService.execute(new Task());
}
} catch (Exception e) {
e.printStackTrace();
}
//休眠10秒,打印日志,观察线程池状态
Thread.sleep(10000);
//每隔3秒提交一个任务
while (true) {
Thread.sleep(3000);
executorService.submit(new Task());
}
}
static class Task implements Runnable {
@Override
public void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "-执行任务");
}
}
}
结论:
- 线程池数达到最大时如果在规定时间内一直有任务进入,则线程池数量不会减少
为何【ArrayList】为线程不安全的?