目录
一:JUC 概述
1)什么是 JUC:
a:在 Java 中,线程部分是一个重点,本篇文章说的 JUC 也是关于线程的。
JUC 就是 java.util.concurrent 工具包的简称。这是一个处理线程的工具包,jdk1.5 出现的。
2)线程 和 进程 概念:
a:进程 与 线程:
-1.进程:指 在系统中,正在运行的一个应用程序;程序一旦运行就是进程;
进程—资源分配的最小单位。
-2.线程:系统分配处理器时间资源的基本单元,或者说,进程之内独立执行的一个单元执行流。
线程—程序执行的最小单位。
b:线程的状态:(流程图)
c:wait 和 sleep:
-1.相同: 一旦执行方法,都可以使当前线程进入阻塞状态。
他们都可以被 interrupted 方法中断。
-2.不同:1.两个方法声明的位置不同:
sleep() --> Thread 类中声明
wait() --> Object 类中声明
2.调用的范围不同:
sleep() --> 任意线程 的 任意位置 都可以调用
wait() --> 必须使用在 同步方法 或 者同步代码块 中
3.关于是否释放同步监视器问题
如果两个方法都是用在,同步代码块 或者 同步方法中
sleep() --> 不会释放同步锁
wait() --> 释放同步锁
d:并发 和 并行:
-1.并发:一个 CPU 同时执行多个任务
-2.并行:多个 CPU 同时执行多个任务
e:用户线程 和 守护线程:
-1.用户线程:
他们在几乎每个方面都是相同的,唯一的区别是 判断 JVM 何时离开。
-2.守护线程:
1.守护线程 是用来服务 用户线程的,通过 start() 方法前调用 thread.setDaemon(true); 此线程设置为守护线程。
当主线程退出,守护线程自动退出。
2.gc() 垃圾回收就是一个典型的守护线程。
f:管程:
二:Lock 接口
三:线程间通信、线程间定制化通信
五:集合的线程安全
1)ArrayList:集合线程不安全演示
public class Lock_main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
//从集合获取内容
System.out.println(list);
}, String.valueOf("ThreadName : " + i)).start();
}
}
}
2)ArrayList 线程不安全解决方案(3)
a:解决方案 1 — Vector:比较古老,使用不多。
List<String> list = new Vector<>();
b:解决方案 2 — Collections:比较古老,使用不多。
List<String> synchronizedList
= Collections.synchronizedList(new ArrayList<>());
synchronizedList.add("123");
c:解决方案 3 — CopyOnWriteArrayList: (写时复制技术)
原理:(并发读,独立写操作)
import java.util.concurrent.CopyOnWriteArrayList;
public class Lock_main {
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<>();
}
}
/** 原理 */
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
3)HashSet、HashMap、线程不安全演示:
public class Lock_main {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
hashSet.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(hashSet.toString());
}, String.valueOf("ThreadName : " + i)).start();
}
}
}