有关多线程的线程安全问题

文章详细解释了线程安全问题,即当多个线程同时修改同一全局变量时可能出现的问题。解决线程安全主要通过使用synchronized锁,确保同一时间只有一个线程能执行特定代码段。文章展示了synchronized锁在修饰静态方法、实例方法和代码块时的不同用法,并通过示例代码说明其效果,所有示例均确保了线程安全,避免了数据冲突。
摘要由CSDN通过智能技术生成

1.首先,什么是线程安全问题?

当多线程同时对同一个全局变量做 '写' 的操作的时候,可能会收到其他的线程的干扰,这个时候就容易发生线程的安全性问题。

2.如何解决线程安全的问题呢?

解决线程安全的问题的核心思想就是上锁,用的较多的应该是(synchronized)锁吧。

那么呢,在同一个jvm当中,当多个线程需要竞争锁的资源的时候,最后只能有一个线程能获取到这把锁,那现在就是哪个线程抢的快,抢到了就能够执行到该代码,那没有获取到锁的呢(也就是没有抢到锁的),它中间就需要经历锁的升级过程(后面可能会讲,也有可能就给个图,也有可能在下一篇文章里),如果没有获取到锁就会一直阻塞等待,

举个栗子:比如现在线程A获取到了锁,但是线程A一直不释放锁

那现在线程B就会一直获取不到锁,那就会一直阻塞等待(说白了就是不动了)

3.上锁的位置

那当然就是在可能发生线程安全的地方上锁辣,不然如果你整个代码都上锁或者一大片都上锁,那不是会降低代码的执行效率吗

4.synchronized锁的基本用法

在多线程的情况下: 需要是同一个对象锁

synchronized(对象锁)

{

可能发生多线程安全的代码

}

其中: 1) 如果将synchronized修饰静态方法,作用于当前类对象(当前类.class)加锁,进入同步代码前要后去当前的对象的锁(写法就是 synchronized(当前类.class))

2) 如果将synchronized修饰实例方法,作用于当前实例加锁,进入同步代码前要获取 当前实例的锁

3)如果将synchronized修饰代码块,指定加锁对象,对给定对象加锁(this锁),进入同步代码块前要获得 给定对象 的锁(也就是this锁)

1.修饰静态方法

package SyncCodInstance;

/**
 * @BelongsProject: threads
 * @BelongsPackage: SyncCodInstance
 * @Author: 晚风
 * @CreateTime: 2023-03-04  15:27
 * @Description: TODO
 * @Version: 1.0
 */
public class ModifyStaticMethods implements Runnable{

    private static Integer count = 100;
    
    @Override
    public void run() {
        while (count >1){
            val();
        }
    }

    private static void val(){
        synchronized (ModifyStaticMethods.class){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count--;
            System.out.println(Thread.currentThread().getName() + "--" + count);
        }
    }

    public static void main(String[] args) {
        // modifyStaticMethods1 的意思是修饰静态方法
        ModifyStaticMethods modifyStaticMethods1 = new ModifyStaticMethods();
        ModifyStaticMethods modifyStaticMethods2 = new ModifyStaticMethods();
        Thread thread1 = new Thread(modifyStaticMethods1);
        Thread thread2 = new Thread(modifyStaticMethods2);
        thread1.start();
        thread2.start();
    }
}

结果如下:(从100到0都是没有重复的)

2.修饰实例方法

package SyncCodInstance;

/**
 * @BelongsProject: threads
 * @BelongsPackage: SyncCodInstance
 * @Author: 晚风
 * @CreateTime: 2023-03-04  15:27
 * @Description: TODO
 * @Version: 1.0
 */
public class ModifyStaticMethods implements Runnable{

    private static Integer count = 100;

    @Override
    public void run() {
        while (count >1){
            val();
        }
    }

    private synchronized void val(){

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count--;
            System.out.println(Thread.currentThread().getName() + "--" + count);

    }

    public static void main(String[] args) {
        // modifyStaticMethods1 的意思是修饰静态方法
//        ModifyStaticMethods modifyStaticMethods1 = new ModifyStaticMethods();
//        ModifyStaticMethods modifyStaticMethods2 = new ModifyStaticMethods();
        ModifyStaticMethods modifyStaticMethods = new ModifyStaticMethods();
        Thread thread1 = new Thread(modifyStaticMethods);
        Thread thread2 = new Thread(modifyStaticMethods);
        thread1.start();
        thread2.start();
    }
}

结果如下:(和上面一样嗷)

  1. 修饰代码块

package SyncCodInstance;

/**
 * @BelongsProject: threads
 * @BelongsPackage: SyncCodInstance
 * @Author: 晚风
 * @CreateTime: 2023-03-04  15:27
 * @Description: TODO
 * @Version: 1.0
 */
public class ModifyStaticMethods implements Runnable{

    private static Integer count = 100;

    @Override
    public void run() {
        while (count >1){
            val();
        }
    }

    private void val(){
        synchronized (this) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count--;
            System.out.println(Thread.currentThread().getName() + "--" + count);
        }
    }

    public static void main(String[] args) {
        // modifyStaticMethods1 的意思是修饰静态方法
//        ModifyStaticMethods modifyStaticMethods1 = new ModifyStaticMethods();
//        ModifyStaticMethods modifyStaticMethods2 = new ModifyStaticMethods();
        ModifyStaticMethods modifyStaticMethods = new ModifyStaticMethods();
        Thread thread1 = new Thread(modifyStaticMethods);
        Thread thread2 = new Thread(modifyStaticMethods);
        thread1.start();
        thread2.start();
    }
}

结果如下:(还是和上面一样嗷)

/*

*同学们注意这三个代码的synchronized()位置

*/

(都是看的课程里面,最后总结和课程里面的知识)

(为了防止犯法,看的是余胜军老师的课,这里标注,上课之后整理的东西然后写的博客)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值