多线程与高并发基础总结-线程的状态与关键字synchronized volatile

线程的状态一共是6个
new

尚未启动

runable

运行状态 runnable 正在运行的时候 被wait join locksupport.park方法进行等待后 编程waiting 状态 在被notify 或者notifyall 或者locksupport.unpack 唤醒 编程runable

blocked

堵塞 等待锁为堵塞 当获得锁后从此状态脱离

Teminated

88状态

Time_waiting

被sleep。或者wait加上时间后 进入此状态 时间结束 则进入runable 状态

waiting

等待状态

关键字 synchronized volatile
synchronized

在多线程同一资源进行访问的时候 进行上锁操作
原子性和可见性
上代码

public class SyTest implements Runnable {

    int count = 0;

    @Override
    public void run() {
        count++;
        System.out.println(Thread.currentThread().getName() + "    count==" + count);
    }

    public static void main(String[] args) {
        // 关键字  synchronized 的验证  可见性和原子性
        // 比如数 在多个线程里进行增加  A线程可以对数进行更改  B 也可以 那么 A B 都不知道其改动的结果 会出现问题
        SyTest syTest = new SyTest();
        for (int i = 0; i < 100; i++) {
            //创建线程 对其进行自增操作 增加100次
            new Thread(syTest, "name" + i).start();

        }

    }
}

结果会出现如图的错误
在这里插入图片描述

50 多加了2次 并且直接46 到50

那么可以给run 方法添加关键字synchronized 把方法锁上。另外一个线程进入前 要去看看锁的状态 如果是同一个线程 那么其锁的重入属性,是可以直接进入。如果资源已经被其他线程使用中 则开始进行自旋,等待,或者进行锁升级 或者自旋期间锁释放后使用资源
synchronized 现在是锁升级。一开始偏向锁 比如有个空间 C 就是锁的记录空间 我一个线程D进来了,会先去C中看看,无值,代表这个线程D是第一个使用的,记录下来。 有值,判断是不是值一致,一致放行,不一致,查看锁的状态。如果已经释放了,那么进入,记录,如果没有释放,还有资源占用,线程D进行自旋,自旋等待锁释放,如果10次后锁还是被占用 升级为重量级的os。

更改后的代码

public class SyTest implements Runnable {

    int count = 0;

    @Override
    public synchronized  void run() {
        count++;
        System.out.println(Thread.currentThread().getName() + "    count==" + count);
    }

    public static void main(String[] args) {
        // 关键字  synchronized 的验证  可见性和原子性
        // 比如数 在多个线程里进行增加  A线程可以对数进行更改  B 也可以 那么 A B 都不知道其改动的结果 会出现问题
        SyTest syTest = new SyTest();
        for (int i = 0; i < 100; i++) {
            //创建线程 对其进行自增操作 增加100次
            new Thread(syTest, "name" + i).start();

        }

    }
}

volatile

保证线程的可见性
比如 有个线程A 和其他线程对一个资源都要进行更改,那么volatile
使用的是缓存一致性协议 当A 做了更改资源 不仅回写 而且告诉其他使用的资源无效了 资源进行了更改的时候 发现无效 则去重新获取
禁止指令重排序
指令重排序 在运行的时候 编译器或者处理器会对代码进行重新的排序
为了更好的优化 或者提高cpu的使用率

上代码

public class Testvloatile {
    //e
    final static private Testvloatile testvloatile = new Testvloatile();

    public static Testvloatile getTestvloatile() {
        return testvloatile;
    }
}

class Testvloatile02 {
    //b
    static private Testvloatile testvloatile02 = null;

    public static synchronized Testvloatile getTestvloatile02() {
        if (testvloatile02 == null) {
            testvloatile02 = new Testvloatile();
        }
        return testvloatile02;
    }
}

class Testvloatile03 {
    //b
    static private volatile Testvloatile testvloatile03 = null;

    public static Testvloatile getTestvloatile03() {
        if (testvloatile03 == null) {
            synchronized (Testvloatile03.class) {
                if (testvloatile03 == null) {
                    testvloatile03 = new Testvloatile();
                }
            }
        }
        return testvloatile03;
    }
}

1)饿汉式单例模式的写法:线程安全

2)懒汉式单例模式的写法:非线程安全

3)双检锁单例模式的写法:线程安全 ➕ volatile 线程安全

主要是三个层面保证禁止重排序
1.ACC_VOLATILE标记
2.内存屏障 4种 在读到ACC_VOLATILE标记时会在内存区读写之前都加屏障。
3.看到读写屏障后 使用lock指令,在指令前后都加lock(屏障),保证前后不乱序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值