多线程 - 7.实例对象与并发访问

本文探讨了线程安全问题,通过实例对比了方法内变量与实例变量在线程安全上的区别,分析了非线程安全变量导致的问题,并提出了使用synchronized关键字来解决线程安全问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法内的变量为线程安全的变量
class ReturnSomething{
    public int get(String a){
        if(a.equals("abc")){
            System.out.println("a set over");
            return 500;
        }else{
            System.out.println("b set over");
            return 10;
        }
    }
}

class ThreadA extends Thread{
    @Override
    public void run(){
        ReturnSomething returnSomething = new ReturnSomething();
        int a = returnSomething.get("abc");
        System.out.println("ThreadA set = " + a);
    }
}

class ThreadB extends Thread{
    @Override
    public void run(){
        ReturnSomething returnSomething = new ReturnSomething();
        int b = returnSomething.get("def");
        System.out.println("ThreadB set = " + b);
    }
}

public class test0{
    public static void main(String[] args){
        Thread a = new ThreadA();
        a.start();
        Thread b = new ThreadB();
        b.start();
    }
}

a set over
b set over
ThreadA set = 500
ThreadB set = 10

实例变量为非线程安全的变量
class ReturnSomething{
    int i = 0;
    public int get(String a){
        if(a.equals("abc")){
            i = 500;
        }else{
            i = 10;
        }
        return i;
    }
}

class ThreadA extends Thread{
    private ReturnSomething returnSomething;
    public ThreadA(ReturnSomething returnSomething){
        super();
        this.returnSomething = returnSomething;
    }
    @Override
    public void run(){
        int a = returnSomething.get("abc");
        if(a == 10){
            System.out.println("a=10, 线程安全出现问题。");
        }
    }
}

class ThreadB extends Thread{
    private ReturnSomething returnSomething;
    public ThreadB(ReturnSomething returnSomething){
        super();
        this.returnSomething = returnSomething;
    }
    @Override
    public void run(){
        super.run();
        int b = returnSomething.get("def");
        if(b == 500){
            System.out.println("b=500, 线程安全出现问题。");
        }
    }
}

public class test1{
    public static void main(String[] args){
        ReturnSomething returnSomething = new ReturnSomething();
        for(int i=0;i<20000;i++){
            Thread a = new ThreadA(returnSomething);
            a.start();
            Thread b = new ThreadB(returnSomething);
            b.start();
        }
    }
}

b=500, 线程安全出现问题。

解决办法:对ReturnSomething类中的get()方法加上 synchroized 关键字

多个线程多个锁实例

多把锁

 public static void main(String[] args){
        ReturnSomething returnSomethingA = new ReturnSomething();
        ReturnSomething returnSomethingB = new ReturnSomething();
        Thread a = new ThreadA(returnSomethingA);
        a.start();
        Thread b = new ThreadB(returnSomethingB);
        b.start();
    }

一把锁

    public static void main(String[] args){
        ReturnSomething returnSomething = new ReturnSomething();
        Thread a = new ThreadA(returnSomething);
        a.start();
        Thread b = new ThreadB(returnSomething);
        b.start();
    }

上面的两把锁是异步进行,ab的执行顺序随机,一把锁是同步进行,a一定在b之前执行。

synchronized
  1. synchronized 锁住的都是对象
  2. synchronized 锁住的对象出现异常后将自动释放锁
  3. synchronized 无法被继承
  4. synchronized 锁的重入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值