多线程访问同步方法情况

1 多线程访问同步方法

1.1 两个线程同时访问一个对象的同步方法

1.1.1 代码演示

package com.wpj;

/**
 *  两个线程同时访问一个对象的同步方法
 */
public class SynchronizedTest1 implements Runnable {

    static SynchronizedTest1 instance = new SynchronizedTest1();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");
    }

    @Override
    public void run() {
        method();
    }
    // synchronized修饰方法默认 this 作为锁
    private synchronized void method() {
        System.out.println("运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("运行结束 " + Thread.currentThread().getName());
    }
}

1.1.2 运行结果

运行中 Thread-0
运行结束 Thread-0
运行中 Thread-1
运行结束 Thread-1
finished

1.2 两个线程访问的是两个对象的同步方法

1.2.1 代码演示

package com.wpj;

/**
 * 两个线程访问的是两个对象的同步方法
 */
public class SynchronizedTest2 implements Runnable {

    static SynchronizedTest2 instance1 = new SynchronizedTest2();
    static SynchronizedTest2 instance2 = new SynchronizedTest2();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");
    }

    @Override
    public void run() {
        synchronized (this) {
            System.out.println("运行中 " + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("运行结束 " + Thread.currentThread().getName());
        }
    }
}

1.2.2 运行结果

运行中 Thread-0
运行中 Thread-1
运行结束 Thread-0
运行结束 Thread-1
finished

1.3 两个线程访问的是synchronized的静态方法

1.3.1 代码演示

package com.wpj;

/**
 * 两个线程访问的是synchronized的静态方法
 */
public class SynchronizedTest3 implements Runnable {

    static SynchronizedTest3 instance1 = new SynchronizedTest3();
    static SynchronizedTest3 instance2 = new SynchronizedTest3();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");
    }

    @Override
    public void run() {
        method();
    }
    // synchronized修饰方法默认 this 作为锁
    private static synchronized void method() {
        System.out.println("运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("运行结束 " + Thread.currentThread().getName());
    }
}

1.3.2 运行结果

运行中 Thread-0
运行结束 Thread-0
运行中 Thread-1
运行结束 Thread-1
finished

1.4 同时访问同步方法与非同步方法

1.4.1 代码演示

package com.wpj;

/**
 * 同时访问同步方法与非同步方法
 */
public class SynchronizedTest4 implements Runnable {

    static SynchronizedTest4 instance = new SynchronizedTest4();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");
    }

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")) {
            method1();
        } else {
            method2();
        }
    }

    // synchronized修饰方法默认 this 作为锁
    private synchronized void method1() {
        System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
    }
    private void method2() {
        System.out.println("没加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("没加锁方法运行结束 " + Thread.currentThread().getName());
    }
}

1.4.2 运行结果

没加锁方法运行中 Thread-1
加锁方法运行中 Thread-0
没加锁方法运行结束 Thread-1
加锁方法运行结束 Thread-0
finished

1.5 访问同一个对象的不同的普通同步方法

1.5.1 代码演示

package com.wpj;

/**
 * 访问同一个对象的不同的普通同步方法
 */
public class SynchronizedTest5 implements Runnable {

    static SynchronizedTest5 instance = new SynchronizedTest5();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");
    }

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")) {
            method1();
        } else {
            method2();
        }
    }

    // synchronized修饰方法默认 this 作为锁
    private synchronized void method1() {
        System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
    }
    private synchronized void method2() {
        System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
    }
}

1.5.2 运行结果

加锁方法运行中 Thread-0
加锁方法运行结束 Thread-0
加锁方法运行中 Thread-1
加锁方法运行结束 Thread-1
finished

1.6 同时访问静态synchronized和非静态synchronized方法

1.6.1 代码演示

package com.wpj;

/**
 * 同时访问静态synchronized和非静态synchronized方法
 */
public class SynchronizedTest6 implements Runnable {

    static SynchronizedTest6 instance = new SynchronizedTest6();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");
    }

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")) {
            method1();
        } else {
            method2();
        }
    }

    // synchronized修饰静态方法 以.class对象 作为锁
    private static synchronized void method1() {
        System.out.println("静态加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("静态加锁方法运行结束 " + Thread.currentThread().getName());
    }
    // synchronized修饰方法默认 this 作为锁
    private synchronized void method2() {
        System.out.println("非静态加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("非静态加锁方法运行结束 " + Thread.currentThread().getName());
    }
}

1.6.2 运行结果

非静态加锁方法运行中 Thread-1
静态加锁方法运行中 Thread-0
非静态加锁方法运行结束 Thread-1
静态加锁方法运行结束 Thread-0
finished

1.7 方法抛出异常后,会释放锁

1.7.1 代码演示

package com.wpj;

/**
 * 方法抛出异常后,会释放锁
 */
public class SynchronizedTest7 implements Runnable {

    static SynchronizedTest7 instance = new SynchronizedTest7();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");
    }

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")) {
            method1();
        } else {
            method2();
        }
    }

    // synchronized修饰静态方法 以.class 作为锁  类锁
    private synchronized void method1() {
        System.out.println("异常加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        throw new RuntimeException();
//        System.out.println("异常加锁方法运行结束 " + Thread.currentThread().getName());
    }
    // synchronized修饰方法默认 this 作为锁  对象锁
    private synchronized void method2() {
        System.out.println("加锁方法运行中 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("加锁方法运行结束 " + Thread.currentThread().getName());
    }
}

1.7.2 运行结果

异常加锁方法运行中 Thread-0
Exception in thread "Thread-0" java.lang.RuntimeException
	at com.wpj.SynchronizedTest7.method1(SynchronizedTest7.java:38)
	at com.wpj.SynchronizedTest7.run(SynchronizedTest7.java:24)
	at java.lang.Thread.run(Thread.java:748)
加锁方法运行中 Thread-1
加锁方法运行结束 Thread-1
finished

2 核心思想

  1. 一把锁只能同时被一个线程所获取,没有拿到锁的线程必须等待。 对应 1,5
  2. 每个实例都对应自己一把锁,不同实例之间互不影响。例外:如果锁对象时*.class或synchronized修饰的静态方法的时候。所有对象共用一把锁。 对应 2,3,4,6
  3. 无论方法正常执行完毕或者抛出异常都会释放锁。对应 7
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值