@[toc]
从底层原理来进行分类
互斥同步
**使用各种互斥锁 Synchronized ReentrantLock Readwritelock**
**使用同步工具
Collections.synchronized(new ArrayList)等
Vector deng**
非互斥同步
原子类
atomic包 原子类
基本类型 :
AtomicInteger 整形,
AtomicLong 长整型
AtiomicBoolean 布尔Array数组 :
AtomicIntergerArray 整形数组
AtomicLongArray 长整形数组
AtomicRefernceArray 引入数组引用类型原子类 :
AtomicReference :引用类型
AtomicStampedReference 引用类型 带时间戳,可以解决ABA问题
升级原子类 :
后面文章会讲到
Adder加法器 :
LongAdder
DoubleAdder
Accumulator累加器 :
LongAccumulator
DoubleAccumulator
结合互斥和非互斥同步
并发容器
ConcurrentHashMap
并发队列
无同步方案不可变
final 关键字
ThreadLocal
1.线程安全问题
什么是线程安全问题:当多个线程同时访问一个全局变量,注意(做写的操作的时候可能会受到别的线程的干扰),做读的操作的时候不会发生线程安全问题
如 ++ , -- 修改等操作 抢火车票的操作,就会引发线程安全问题
模拟场景:
package com.yxl.demo.ThreadTest;
public class test5 {
public static void main(String[] args) {
TestDemo thread = new TestDemo();
Thread t1 = new Thread(thread,"窗口一");
Thread t2 = new Thread(thread,"窗口二");
t1.start();
t2.start();
}
}
class TestDemo implements Runnable{
//共享的火车票变量
private int count = 100;
//重寫run方法
@Override
public void run() {
while (count > 0){
try {
//休眠一下 方便出现并发问题
Thread.sleep(50);
}catch (Exception e){
e.getMessage();
}
sale();
}
}
//卖票
public void sale(){
if(count > 0){
System.out.println(Thread.currentThread().getName() +"出售 :" +(100 - count + 1));
count--;
}
}
}
运行结果如下:会发现出现卖重复票的问题
解决这个线程安全问题
内置锁(Synchronized)
- 保证线程原子性,当先车管进入方法自动的获取锁,当某一个线程获取到锁后,其他线程就会等待,
- 锁的特性:只有一个线程进行使用。
- 放程序执行完毕之久,就会把锁释放,但是锁会降低程序的运行效率,
Synchronized 也是 重入锁,内置锁也是互斥锁
使用 Synchronized 有两种方式, 同步方法(使用的是this锁),同步代码块
synchronized 修饰方法使用锁是当前this锁。
synchronized 修饰静态方法使用锁是当前类的字节码文件
显示锁 (lock锁)
解决方案 :
1.同步方法
2. 同步代码块
使用同步代码块的时候 注意(锁一定要使用同一个锁 )
问:如何解决多线程之间线程安全问题
*答:使用多线程之间同步synchronized或使用锁(lock)。*
问:为什么使用线程同步或使用锁能解决线程安全问题呢?
*答:将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。*
问:什么是多线程之间同步
*答:当多个线程共享同一个资源,不会受到其他线程的干扰。*