并发中级篇
1. JUC概述
1.1 JUC
- 在JAVA中,线程部分是一个重点,本篇文章说的是JUC也是关于线程的。JUC就是java.util.concurrent工具包的简称。这是一个处理线程的工具包,JDK1.5开始出现的。
1.2 线程和进程
- 进程与线程:
- 一个进程可包含多个线程
- 线程的几个状态:
- 线程状态枚举类:
- NEW
- RUNNABLE
- BLOCKED
- WAITING
- TIMED_WAITING
- TERMINATED
- 线程状态枚举类:
- wait和sleep:
- sleep是Thread中的静态方法,wait是Object中的方法,任何对象实例都能调用
- sleep不会释放锁。wait会释放锁,但是调用它的前提是的当前线程占有锁(即代码要在synchronized中)
- 他们都可以被interrupt方法中断
- 并发和并行:
- 管程:
- 线程操作,首先持有管程对象,然后才能执行方法。当在方法中,其余的线程不能再获取同一个管程对象;在方法运行完之后,最后再释放管程对象。
- 用户线程和守护线程:
- 用户线程:自定义线程
- 守护线程:比如说垃圾回收,运行在后台
2. Lock接口
2.1 Synchronized
- Synchronized作用范围
- 1.修饰一个代码块
- 2.修饰一个方法,被修饰的方法称为同步方法。
- 3.修改一个静态方法,其作用范围是整个静态方法。作用的对象是这个类的所有对象。
- 4.修改一个类,其作用范围是synchronized后面括号括起来的部分,作用对象是这个类的所有对象
- Synchronized实现卖票例子
- 多线程编程步骤(上)
- 1.创建资源类,在资源类创建属性和操作方法
- 2.创建多个线程,调用资源类的操作方法
package com.atguigu.sync;
//1.第一步:创建资源类,定义属性和方法
class Ticket{
//票数
private int number = 30;
//操作方法
public synchronized void sale(){
//卖票过程
if(number>0){
System.out.println(Thread.currentThread().getName()+":还有:" + (number--)
+ ",卖出后剩下:" + number);
}
}
}
public class SaleTicket {
//第二步:创建多个线程
public static void main(String[] args) {
//创建Ticket对象
Ticket ticket = new Ticket();
//创建三个线程
new Thread(new Runnable() {
@Override
public void run() {
//调用卖票方法
for(int i=0; i<40; i++){
ticket.sale();
}
}
},"AA").start();
//第二个线程
new Thread(new Runnable() {
@Override
public void run() {
//调用卖票方法
for(int i=0; i<40; i++){
ticket.sale();
}
}
},"BB").start();
//第三个线程
new Thread(new Runnable() {
@Override
public void run() {
//调用卖票方法
for(int i=0; i<40; i++){
ticket.sale();
}
}
},"CC").start();
}
}
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.2.4\lib\idea_rt.jar=56685:D:\IntelliJ IDEA 2020.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\day01\out\production\day01;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.atguigu.sync.SaleTicket
AA:还有:30,卖出后剩下:29
AA:还有:29,卖出后剩下:28
AA:还有:28,卖出后剩下:27
AA:还有:27,卖出后剩下:26
AA:还有:26,卖出后剩下:25
AA:还有:25,卖出后剩下:24
AA:还有:24,卖出后剩下:23
AA:还有:23,卖出后剩下:22
AA:还有:22,卖出后剩下:21
AA:还有:21,卖出后剩下:20
AA:还有:20,卖出后剩下:19
AA:还有:19,卖出后剩下:18
AA:还有:18,卖出后剩下:17
AA:还有:17,卖出后剩下:16
AA:还有:16,卖出后剩下:15
AA:还有:15,卖出后剩下:14
AA:还有:14,卖出后剩下:13
AA:还有:13,卖出后剩下:12
AA:还有:12,卖出后剩下:11
AA:还有:11,卖出后剩下:10
AA:还有:10,卖出后剩下:9
AA:还有:9,卖出后剩下:8
AA:还有:8,卖出后剩下:7
AA:还有:7,卖出后剩下:6
AA:还有:6,卖出后剩下:5
AA:还有:5,卖出后剩下:4
AA:还有:4,卖出后剩下:3
AA:还有:3,卖出后剩下:2
AA:还有:2,卖出后剩下:1
AA:还有:1,卖出后剩下:0
Process finished with exit code 0
2.2 Lock接口
- Lock锁提供了比使用synchronized同步方法和语句可以获得更多的操作
- Lock不是java内置的,synchronized是java内置的
- synchronized是自动上锁,自动释放锁;lock是手动上锁,手动释放锁
- lock可以响应中断,但是synchronized无法响应中断
package com.atguigu;
import java.util.concurrent.locks.ReentrantLock;
//1.第一步:创建资源类,定义属性和方法
class LTicket{
//票数
private int number = 30;
//操作方法
private final ReentrantLock lock = new ReentrantLock();
public void sale(){
//卖票过程
lock.lock();
try {
if (number > 0) {
System.out.println(Thread.currentThread().getName() + ":还有:" + (number--)
+ ",卖出后剩下:" + number);
}
}finally {
lock.unlock();
}
}
}
public class LSaleTicket {
public static void main(String[] args) {
//
LTicket ticket = new LTicket();
//创建线程的方式
new Thread(()->{ //lang表达式
for(int i=0; i<40; i++){
ticket.sale();
}
},"AA").start();
new Thread(()->{
for(int i=0; i<40; i++){
ticket.sale();
}
},"BB").start();
new Thread(()->{
for(int i=0; i<40; i++){
ticket.sale();
}
},"CC").start();
}
}
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.2.4\lib\idea_rt.jar=56749:D:\IntelliJ IDEA 2020.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\day01\out\production\day01;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.atguigu.LSaleTicket
AA:还有:30,卖出后剩下:29
AA:还有:29,卖出后剩下:28
AA:还有:28,卖出后剩下:27
AA:还有:27,卖出后剩下:26
AA:还有:26,卖出后剩下:25
BB:还有:25,卖出后剩下:24
BB:还有:24,卖出后剩下:23
BB:还有:23,卖出后剩下:22
BB:还有:22,卖出后剩下:21
BB:还有:21,卖出后剩下:20
BB:还有:20,卖出后剩下:19
BB:还有:19,卖出后剩下:18
BB:还有:18,卖出后剩下:17
BB:还有:17,卖出后剩下:16
BB:还有:16,卖出后剩下:15
BB:还有:15,卖出后剩下:14
BB:还有:14,卖出后剩下:13
BB:还有:13,卖出后剩下:12
BB:还有:12,卖出后剩下:11
BB:还有:11,卖出后剩下:10
BB:还有:10,卖出后剩下:9
BB:还有:9,卖出后剩下:8
BB:还有:8,卖出后剩下:7
BB:还有:7,卖出后剩下:6
BB:还有:6,卖出后剩下:5
BB:还有:5,卖出后剩下:4
BB:还有:4,卖出后剩下:3
BB:还有:3,卖出后剩下:2
BB:还有:2,卖出后剩下:1
BB:还有:1,卖出后剩下:0
Process finished with exit code 0
2.3 创建多线程的多种方式
2.4 使用LOCK实现卖票
3. 线程间的通信
- 多线程步骤:
- 1.创建资源类,在资源类创建属性和操作方法
- 2.在资源类操作方法
- (1).判断
- (2).干活
- (3).通知
- 3.创建多个线程,调用资源类的操作方法
package com.atguigu.sync;
//创建一个资源类
class Share {
private int number = 0;
//+1的方法
public synchronized void incr() throws InterruptedException {
if (number != 0) {
//判断number是否为0,如果不为0,等待
this.wait();
}
//如果number=0,+1
number++;
System.out.println(Thread.currentThread().getName() + "::" + number);
//通知其他线程
this.notifyAll();
}
//-1的方法
public synchronized void decr() throws InterruptedException {
if(number!=1){
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName() + "::" + number);
this.notifyAll();
}
}
public class ThreadDemo01 {
public static void main(String[] args) {
//第三步:创建多个线程,调用资源类的操作方法
Share share = new Share();
//创建线程
new Thread(()->{
for(int i=1;i<=10;i++){
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();
new Thread(()->{
for(int i=1;i<=10;i++){
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
}
}
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.2.4\lib\idea_rt.jar=56980:D:\IntelliJ IDEA 2020.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\day01\out\production\day01;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.atguigu.sync.ThreadDemo01
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
Process finished with exit code 0
虚假唤醒问题解决方案:
while(number != 1){ //将判断条件改为循环的形式
this.wait();
}
package com.atguigu.sync;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//创建资源类
class Share1 {
private int num=0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
//+1方法
public void incr() throws InterruptedException {
//上锁
lock.lock();
try{
//判断
while(num != 0){
condition.await();
}
//干活
num++;
System.out.println(Thread.currentThread().getName() + "::" + num);
//通知
condition.signalAll();
} finally{
//解锁操作
lock.unlock();
}
}
//-1方法
public void decr() throws InterruptedException {
lock.lock();
try{
//判断
while(num!=1){
condition.await();
}
//操作
num--;
//通知
condition.signalAll();
}finally{
lock.unlock();
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Share share = new Share();
//线程AA
new Thread(()->{
for(int i=1;i<=10;i++){
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();
//线程BB
new Thread(()->{
for(int i=1;i<=10;i++){
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
//线程CC
new Thread(()->{
for(int i=1;i<=10;i++){
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"CC").start();
//线程DD
new Thread(()->{
for(int i=1;i<=10;i++){
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"DD").start();
}
}
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.2.4\lib\idea_rt.jar=57137:D:\IntelliJ IDEA 2020.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\day01\out\production\day01;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.atguigu.sync.ThreadDemo2
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
AA::1
BB::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
CC::1
DD::0
Process finished with exit code 0
4. 线程间定制化通信
- 启动三个线程,按照如下的要求进行操作:
- AA打印5次,BB第二执行,CC打印15
- AA打印5次,BB第二执行,CC打印15
package com.atguigu.sync;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//创建资源类
class ShareResource{
//属性:标志位
private int flag = 1;//1AA 2BB 3CC
//创建Lock锁
private Lock lock = new ReentrantLock();
//创建三个condition
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
//打印5次
public void print5(int loop) throws InterruptedException {
//上锁
lock.lock();
try{
//判断
while(flag!=1){
//等待
c1.await();
}
//干活
for(int i=1; i<=5; i++){
System.out.println(Thread.currentThread().getName()+ "::" + i + ":轮数:" + loop);
}
//通知
flag = 2;//先修改标志位
c2.signal();//在通知BB线程
}finally{
//释放锁
lock.unlock();
}
}
//打印10次
public void print10(int loop) throws InterruptedException{
lock.lock();
try{//等待
while(flag!=2){
c2.await();
}
//干活
for(int i=1; i<=10; i++){
System.out.println(Thread.currentThread().getName()+ "::" + i + ":轮数:" + loop);
}
//通知
flag=3;
c3.signal();
}finally{
lock.unlock();
}
}
//打印15次
public void print15(int loop) throws InterruptedException{
lock.lock();
try{//等待
while(flag!=3){
c3.await();
}
//干活
for(int i=1; i<=10; i++){
System.out.println(Thread.currentThread().getName()+ "::" + i + ":轮数:" + loop);
}
//通知
flag=1;
c1.signal();
}finally{
lock.unlock();
}
}
}
public class ThreadDemo3 {
public static void main(String[] args) {
//创建资源
ShareResource shareResource = new ShareResource();
//创建三个线程
new Thread(()->{
for(int i=1; i<=10; i++){
try {
shareResource.print5(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();
new Thread(()->{
for(int i=1; i<=10;i++){
try {
shareResource.print10(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
new Thread(()->{
for(int i=1; i<=10;i++){
try {
shareResource.print15(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"CC").start();
}
}
5. 集合的线程安全
5.1 集合线程不安全演示
package com.atguigu.sync;
/*
* list集合线程不安全
*
*/
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class ThreadDemo4 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
for(int i=0; i<30; i++){
new Thread(()->{
//向集合中添加内容
list.add(UUID.randomUUID().toString().substring(0,8));
//从集合中获取内容
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.2.4\lib\idea_rt.jar=57347:D:\IntelliJ IDEA 2020.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\day01\out\production\day01;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.atguigu.sync.ThreadDemo4
[aadea00b, ae5a5aa6]
[aadea00b, ae5a5aa6, 940e1a33]
[aadea00b, ae5a5aa6]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e, 60b1002c]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e, 60b1002c, c9d5db9d]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e, 60b1002c, c9d5db9d, a0d05cd6]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e, 60b1002c, c9d5db9d, a0d05cd6, 41b0804e]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e, 60b1002c, c9d5db9d, a0d05cd6, 41b0804e, 5f4a2711]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e, 60b1002c, c9d5db9d, a0d05cd6, 41b0804e, 5f4a2711, dc55e916]
[aadea00b, ae5a5aa6, 940e1a33, 1ec708cb, bc4f7130, da4e83cd, 8c063487, e9f50606, 9f580680, 6007e631, 5c0c046e, 5a539b10, 048d2bc8, 75c093e2, 5dc8d0a8, e3192fbc, b7bfad0c, 722f6e43, 36f20de3, a3cb0146, b4614891, 968399d4, 32c5652e, 60b1002c, c9d5db9d, a0d05cd6, 41b0804e, 5f4a2711, dc55e916, 270dba75]
Exception in thread "17" Exception in thread "2" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at com.atguigu.sync.ThreadDemo4.lambda$main$0(ThreadDemo4.java:20)
at java.lang.Thread.run(Thread.java:748)
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at com.atguigu.sync.ThreadDemo4.lambda$main$0(ThreadDemo4.java:20)
at java.lang.Thread.run(Thread.java:748)
Process finished with exit code 0
5.2 解决方案-vector
vector源代码:
/**
* Adds the specified component to the end of this vector,
* increasing its size by one. The capacity of this vector is
* increased if its size becomes greater than its capacity.
*
* <p>This method is identical in functionality to the
* {@link #add(Object) add(E)}
* method (which is part of the {@link List} interface).
*
* @param obj the component to be added
*/
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
package com.atguigu.sync;
/*
* list集合线程不安全
*
*/
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
public class ThreadDemo4 {
public static void main(String[] args) {
//创建ArrayList集合
// List<String> list = new ArrayList<>();
List<String> list = new Vector<>();
for(int i=0; i<30; i++){
new Thread(()->{
//向集合中添加内容
list.add(UUID.randomUUID().toString().substring(0,8));
//从集合中获取内容
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.2.4\lib\idea_rt.jar=57370:D:\IntelliJ IDEA 2020.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\day01\out\production\day01;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.atguigu.sync.ThreadDemo4
[c4689892, 90a47afe, b554b86a]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf, 24642a40, a6327810]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828]
[c4689892, 90a47afe, b554b86a, 8a79cbf2]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf, 24642a40, a6327810, fabd7978, 8a92c59a]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf, 24642a40, a6327810, fabd7978, 8a92c59a, 56c43004]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf, 24642a40, a6327810, fabd7978, 8a92c59a, 56c43004]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf, 24642a40, a6327810, fabd7978]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf, 24642a40]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e]
[c4689892, 90a47afe, b554b86a, 8a79cbf2, 094c3828, 07b0c7d0, 98f98527, 4410a510, 1d9a70da, 0bb1269d, d3d5350e, 85444775, 3a909675, e86e5c31, 4c2e2b27, b8b7e65b, 6b4ad455, dd134c0d, 3e86df48, cf282a62, a41287c0, 25633381, 36bb706c, 888e3b81, 1dc2eedf, 24642a40, a6327810, fabd7978, 8a92c59a]
Process finished with exit code 0
5.3 解决方案-Collection
java的Collections.synchronizedList
方法解决线程安全问题:
package com.atguigu.sync;
/*
* list集合线程不安全
*
*/
import java.util.*;
public class ThreadDemo4 {
public static void main(String[] args) {
//创建ArrayList集合
List<String> list = Collections.synchronizedList(new ArrayList<>());
for(int i=0; i<30; i++){
new Thread(()->{
//向集合中添加内容
list.add(UUID.randomUUID().toString().substring(0,8));
//从集合中获取内容
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
5.4 解决方案-CopyOnWriteArrayList类
- 写时复制技术 :
package com.atguigu.sync;
/*
* list集合线程不安全
*
*/
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ThreadDemo4 {
public static void main(String[] args) {
//创建ArrayList集合
List<String> list = new CopyOnWriteArrayList<>();
for(int i=0; i<30; i++){
new Thread(()->{
//向集合中添加内容
list.add(UUID.randomUUID().toString().substring(0,8));
//从集合中获取内容
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
5.5 HashSet 与 HashMap
Set<String> set = new CopyOnWriteArraySet<>();
创建set对象解决方案Map<String,String> map = new ConcurrentHashMap<>();
创建map对象解决方案