多线程synchronized和synchronized static方法的区别

synchronized static和synchronized 关键字

1.synchronized satic 方法,如果是一个方法加上static关键字和synchronized。static一定不属于任何对象,属于一个类。那么它锁的是当前类的对象的class对象。因为Java中无论一个类有多少个对象,这些对象会对应唯一一个Class对象,因为当前线程分别访问了同一个类的两个对象的static,synchronized方法时候。他们执行的顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程开始。(非常重要)
2.synichronized关键字锁的是对象锁,

代码例子:

class Resource {
    public synchronized void method1() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method1 running...");
    }

    public synchronized void method2() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method2 running...");
    }

    public synchronized static void method3() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method3 running...");
    }

    public synchronized static void method4() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method4 running...");
    }
}

//线程1-调用 synchronized方法
class Method1Thread extends Thread {

    private Resource syncMethodTest;

    public Method1Thread(Resource syncMethodTest) {
        this.syncMethodTest = syncMethodTest;
    }

    @Override
    public void run() {
        syncMethodTest.method1();
    }
}

//线程2-调用 synchronized方法
class Method2Thread extends Thread {

    private Resource resource;

    public Method2Thread(Resource syncMethodTest) {
        this.resource = syncMethodTest;
    }

    @Override
    public void run() {
        resource.method2();
    }
}

//线程3-调用 synchronized static方法
class Method3Thread extends Thread {

    private Resource syncMethodTest;

    public Method3Thread(Resource syncMethodTest) {
        this.syncMethodTest = syncMethodTest;
    }

    @Override
    public void run() {
        syncMethodTest.method3();
    }
}

//线程4-调用 synchronized static方法
class Method4Thread extends Thread {

    private Resource syncMethodTest;

    public Method4Thread(Resource syncMethodTest) {
        this.syncMethodTest = syncMethodTest;
    }

    @Override
    public void run() {
        syncMethodTest.method4();
    }
}

测试类:

/**
 * Created by qianyi on 2017/9/9.
 */
public class StaticSynicTest {

    public static void main(String[] args) {
        Resource resource = new Resource();
        Resource resource1 = new Resource();
        //访问synchronized方法
        Thread t1 = new Method1Thread(resource);
        //访问synchronized方法
        Thread t2 = new Method2Thread(resource);
        //访问synchronized static方法
        Thread t3 = new Method3Thread(resource);
        //访问synchronized static方法        
        Thread t4 = new Method4Thread(resource);
        //访问synchronized static方法
        Thread t6 = new Method4Thread(resource1);
        //访问synchronized 方法
        Thread t5 = new Method2Thread(resource1);
        /**
         * 都是对同一个实例的synchronized域访问,因此不能被同时访问,
         */
        //        t1.start();
        //        t2.start();

        /**
         *是针对不同实例的,实例有两个,针对的不同的resource和resource1,因此可以同时被访问
         */
        //        t1.start();
        //        t5.start();

        /**
         *t1锁的是对象锁,t4锁的是Class锁。可以同时访问。
         */
//        t4.start();
//        t1.start();
        /**
         * t4和t6分别操作的资源不同,但是锁的是class锁,所以不可以同时访问
         */
//        t4.run();
//        t6.run();
    }
}

总结

1.synchronized 与static synchronized锁的范围不同,synchronized锁的是对象,static synchronized锁是class对象,两个互相不受影响。可以同时被访问。
2.synchronized static防止多个线程同时访问某一个方法。上面的例子是防止多个线程同时method3 和method4,即使操作资源的不同,因为锁的是Resource.class。class在真个内存中之后一个。所以多个线程不能同时访问。
3.synchronized锁的是对象。针对同一个实例(同一个对象),一定是同一个实例,多个线程不能同时访问。如果是不同的实例,那么也可以同时访问,锁的是对象(Resrouce的实例,针对同一个实例的多个线程访问必须遵守顺序)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值