synchronized同步机制,修饰类和修饰对象的区别

Posted super-chao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized同步机制,修饰类和修饰对象的区别相关的知识,希望对你有一定的参考价值。

synchronized用法

synchronized修饰的对象有几种:

  • 修饰一个类:其作用的范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象

  • 修饰一个方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象

  • 修饰一个静态的方法:其作用的范围是整个方法,作用的对象是这个类的所有对象

  • 修饰一个代码块:被修饰的代码块称为同步语句块,其作用范围是大括号{}括起来的代码块,作用的对象是调用这个代码块的对象

 

synchronized(this)是对象锁,如果有多个对象就有相对应的多个锁。(修饰一个代码块)
synchronized(类的名.class)是全局锁,不管有几个对象就公用一把锁。(修饰一个类)

方法内的同步代码块:

package test.synchronizedtest.test1;

public class ObjectService {
        public void serviceMethodA(){
            try {
                synchronized (this) {
                    System.out.println("A begin time = " + System.currentTimeMillis());
                    Thread.sleep(2000);
                    System.out.println("A end time = " + System.currentTimeMillis());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void serviceMethodB(){
            synchronized (this){
                System.out.println("B begin time ="+System.currentTimeMillis());
                System.out.println("B end time" + System.currentTimeMillis());
            }
        }
        
        //测试同步代码块 synchronized
        public void serviceMethodC(String thread){
            /*synchronized (this) {
                System.out.println("A begin time = " + System.currentTimeMillis());
                Thread.sleep(2000);
                System.out.println("A end time = " + System.currentTimeMillis());
            }*/
            
            /*synchronized (this){
                for(int i=0;i<50;i++){
                    System.out.println(thread + i);
                }
            }*/
        
            /*for(int i=0;i<50;i++){
                System.out.println(thread + i);
            }*/
            
            synchronized (ObjectService.class){
                for(int i=0;i<50;i++){
                    System.out.println(thread + i);
                }
            }
        }

}

synchronized (this){...修饰对象,如果有多个对象就有相对应的多个锁。

synchronized (ObjectService.class){...不管有几个对象就公用一把锁。

线程类:

ThreadA:

package test.synchronizedtest.test1;

public class ThreadA extends Thread{
    private ObjectService service;
    public ThreadA(ObjectService service){
        super();
        this.service=service;
    }
    public void run(){
        super.run();
        //service.serviceMethodA();
        service.serviceMethodC("ThreadA");
    }

}

ThreadB:

package test.synchronizedtest.test1;

public class ThreadB extends Thread{
    private  ObjectService service;
    public ThreadB(ObjectService service){
        super();
        this.service=service;
    }

    public void run (){
        super.run();
        //service.serviceMethodB();
        service.serviceMethodC("ThreadB");
    }

}

测试类Test:

package test.synchronizedtest.test1;

public class Test {
    public static void main(String[] args) {
        ObjectService service = new ObjectService();
        ObjectService service2 = new ObjectService();
        ThreadA a = new ThreadA(service);
        a.setName("a");
        a.start();
        ThreadB b = new ThreadB(service2);
        b.setName("b");
        b.start();
    }
}

synchronized (this){...输出结果:

技术分享图片

不同对象对应不同的锁,线程交替执行。

synchronized (ObjectService.class){...输出结果:

技术分享图片

不同的对象共用一个锁,当一个线程执行完后才能执行另一个线程。

 

总结:作用的对象是这个类的所有对象,则不同对象共用锁;否则,不同的对象对应不同的锁。

 


以上是关于synchronized同步机制,修饰类和修饰对象的区别的主要内容,如果未能解决你的问题,请参考以下文章

JAVA高并发程序设计学习:Synchronized同步代码块具体使用方法

synchronized同步关键字

synchronized

Java多线程学习篇synchronized

Java多线程的同步机制(synchronized)

Synchronized