一、synchronized同步方法

论:“线程安全”与“非线程安全”是多线程的经典问题。synchronized()方法就是解决非线程安全的。

1、方法内的变量为线程安全

public void addI(String username) {
        try {
            int num = 0;     \\方法内的变量为线程安全
            if (username.equals("a")) {
                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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

2、实例变量非线程安全

public class HasSelfPrivateNum {
    private int num = 0;    \\实例变量非线程安全
    public void addI(String username) {
        try {
            if (username.equals("a")) {
                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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

解决方法: 方法前加synchronized关键字。

public class HasSelfPrivateNum {

    private int num = 0;

    synchronized public void addI(String username) {
       ..............
    }

}

3、多个对象多个锁

HasSelfPrivateNum.java

public class HasSelfPrivateNum {

    private int num = 0;

    synchronized public void addI(String username) {
        try {
            if (username.equals("a")) {
                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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

ThreadA

    
    public class ThreadA extends Thread {
    
        private HasSelfPrivateNum numRef;
    
        public ThreadA(HasSelfPrivateNum numRef) {
            super();
            this.numRef = numRef;
        }
    
        @Override
        public void run() {
            super.run();
            numRef.addI("a");
        }
    
    }
ThreadB
public class ThreadB extends Thread {

    private HasSelfPrivateNum numRef;

    public ThreadB(HasSelfPrivateNum numRef) {
        super();
        this.numRef = numRef;
    }

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

}

RUN

public class Run {

    public static void main(String[] args) {

        HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();
        HasSelfPrivateNum numRef2 = new HasSelfPrivateNum();

        ThreadA athread = new ThreadA(numRef1);
        athread.start();

        ThreadB bthread = new ThreadB(numRef2);
        bthread.start();

    }

}

结果:创建了2个业务实例,产生2个锁,所以运行结果是异步的。同步为synchronized  异步:asynchronized

四、java多线程核心技术——synchronized同步方法与synchronized同步快

4、synchronized 锁重入

                   当一个线程得到一个对象锁时,再次请求该对象锁时是可以再次得到该对象的锁的。继承关系也可重入锁。

                   当一个线程执行发生异常时,其持有的锁会自动释放。

                   同步不具有继承性。的在子类方法中添加synchronized的关键字。

public class HasSelfPrivateNum {
    synchronized public void service1() {
        System.out.println("service1");
        service2();
    }

    synchronized public void service2() {
        System.out.println("service2");
        service3();
    }

    synchronized public void service3() {
        System.out.println("service3");
    }
}
HasSelfPrivateNum.java

相关文章:

  • 2022-12-23
  • 2021-07-17
  • 2022-12-23
  • 2021-05-18
  • 2017-11-22
  • 2021-08-29
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-07-01
  • 2021-10-27
  • 2021-08-29
  • 2021-12-15
  • 2021-10-19
相关资源
相似解决方案