对象及变量的并发访问

本文详细介绍了Java中synchronized同步方法和同步代码块的使用,包括实例变量的线程安全问题、多个对象多个锁的概念,以及synchronized(this)、synchronized(非this)和synchronized(class)的应用和区别,通过实例分析展示了其在多线程并发访问中的作用和效果。
摘要由CSDN通过智能技术生成

对象及变量的并发访问

2.1 synchronized同步方法

首先在这里说明两个概念:线程安全和非线程安全

线程安全:就是获取的实例变量的值经过同步处理不会出现脏读的现象。

非线程安全:就是多个线程对同一个对象中的实例变量进行并发访问时发生脏读的,即取到的数据其实是被更改过的。

2.1.1 实例变量非线程安全

下面我们用代码来说明一下非线程安全,HasSelfPrivateNum.java代码如下:

public class HasSelfPrivateNum {
   
    private int num = 0;

    public void addI(String username) {
   
        try {
   
            if (("a").equals(username)) {
   
                num = 100;
                System.out.println("a set over");
                Thread.sleep(2000);
            } else {
   
                num = 200;
                System.out.println("b set over");
            }
            System.out.println(username + " num= " + num);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }

    }
}

自定义线程类 MyThread1.java, MyThread2.java 代码如下:

public class MyThread1 extends Thread{
   
    private  HasSelfPrivateNum hasSelfPrivateNum;
    public MyThread1(HasSelfPrivateNum hasSelfPrivateNum){
   
        this.hasSelfPrivateNum=hasSelfPrivateNum;
    }
    @Override
    public void run() {
   
        hasSelfPrivateNum.addI("a");
    }
}

public class MyThread2 extends Thread{
   
    private HasSelfPrivateNum hasSelfPrivateNum;
    public MyThread2 (HasSelfPrivateNum hasSelfPrivateNum){
   
        this.hasSelfPrivateNum=hasSelfPrivateNum;
    }

    @Override
    public void run() {
   
        hasSelfPrivateNum.addI("b");
    }
}

创建运行类 Test.java,代码如下:

public class Test {
   
    public static void main(String[] args) {
   
        HasSelfPrivateNum hasSelfPrivateNum=new HasSelfPrivateNum();
        MyThread1 myThread1=new MyThread1(hasSelfPrivateNum);
        myThread1.start();
        MyThread2 myThread2=new MyThread2(hasSelfPrivateNum);
        myThread2.start();
    }
}

代码运行运行结果:

a set over
b set over
b num= 200
a num= 200

两个线程同时访问一个没有同步的方法,如果两个线程同时操作业务对象中的实例变量,则会出现 “非线程安全”的问题,那我们如何解决这个问题,只需要在 public void addI(String username)方法前面加上关键字synchronized即可 ,更改后方法的代码如下:

public synchronized void addI(String username)

再次运行程序结果如下:

a set over
a num= 100
b set over
b num= 200

所以得出结论,两个线程访问同一个对象中的同步方法时一定是线程安全的。

2.1.2 多个对象多个锁

其他类的代码不变,修改运行类 Test.java,代码如下:

public class Test {
   
    pu
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值