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

方法内的变量为线程安全的变量
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 锁的重入

猜你喜欢

转载自blog.csdn.net/weixin_43845524/article/details/106804023