synchronized 作用域问题

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33082731/article/details/80689355

昨天项目上因为高并发访问导致数据出现了问题,觉得很奇怪,自己写了Demo又试了一遍同步锁synchronized。
最一开始的Demo一直没有成功加锁

public class Test{
    public static void main(String[] args) {
        MyTest myTest1 = new MyTest("thread1");
        Thread thread1 = new Thread(myTest1);
        thread1.start();

        MyTest myTest2 = new MyTest("thread2");
        Thread thread2 = new Thread(myTest2);
        thread2.start();
    }

}

class MyTest implements Runnable{
    String name;
    MyTest(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        try {
            LockTest lockTest = new LockTest();
            lockTest.houh(name);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


class LockTest {
    public synchronized void houh(String name) throws InterruptedException {
        for(int i = 0; i < 100;i++) {
            System.out.println(name +"     "+ i);
        }
    }
}

这里写图片描述
两个线程在加锁的方法上交叉执行的。

emmm,这怎么和我想的不一样呢,然后就开始查找资料。

原来synchronized加在static方法上是以这个Class作为锁的,但加在非static方法上,是以这个Class new 出来的对象作为锁的。

变为static的方法,不需要new对象了,再试一下Demo

public class Test{
    public static void main(String[] args) {
        MyTest myTest1 = new MyTest("thread1");
        Thread thread1 = new Thread(myTest1);
        thread1.start();

        MyTest myTest2 = new MyTest("thread2");
        Thread thread2 = new Thread(myTest2);
        thread2.start();
    }

}

class MyTest implements Runnable{
    String name;
    MyTest(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        try {
            LockTest .houh(name);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


class LockTest {
    public static synchronized void houh(String name) throws InterruptedException {
        for(int i = 0; i < 100;i++) {
            System.out.println(name +"     "+ i);
        }
    }
}

果真是一个线程执行结束,另一个线程才执行的。
这里写图片描述

那非static方法需要加类级别的锁应该怎么办呢?可以通过锁定代码块方式,指定类为锁,这样也可以实现类上加锁或者说代码块加锁。

public void houh(String name) throws InterruptedException {
    synchronized(LockTest.class) {
        for(int i = 0; i < 100;i++) {
            System.out.println(name +"     "+ i);
        }
    }
}
展开阅读全文

没有更多推荐了,返回首页