对象及变量的并发访问-----synchronized同步(6)-----静态同步synchoronized synchronized(class)代码块的区别

一、将synchronized关键字加到static方法上的时候是给Class类加了锁,而给非static方法加synchronized是给Class类实例的对象加了锁。

  创建一个类,其中两个synchronized修饰的静态方法,一个是修饰的非静态方法,将第一个的静态方法sleep3秒,观察两个静态方法的锁,和静态和非静态的锁,如果都是同一个锁,则会发现应该顺序不变,第二三个方法都会等待第一个方法三秒。

  实验如下:

  创建Service类:

package service;

/**
 * Created by zhc on 2017/10/10
 */
public class Service6 {
    synchronized public static void printA(){
      try {
          System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"进入printA");
          Thread.sleep(3000);
          System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"离开printA");
      }catch (InterruptedException e){
          e.printStackTrace();
      }
    }

    synchronized public static void printB(){
        System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"进入printB");
        System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"离开printB");
    }

    synchronized public  void printC(){
        System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"进入printC");
        System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"离开printC");
    }
}

  三个进程分别调用单个方法:

package extthread;

import service.Service6;

/**
 * Created by zhc on 2017/10/10
 */
public class Thread1 extends Thread {
    private Service6 service;
    public Thread1(Service6 service){
        super();
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printA();
    }
}
package extthread;

import service.Service6;

/**
 * Created by zhc on 2017/10/10
 */
public class Thread2 extends Thread{
    private Service6 service;
    public Thread2(Service6 service){
        super();
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printB();
    }
}
package extthread;

import service.Service6;

/**
 * Created by zhc on 2017/10/10
 */
public class Thread3 extends Thread{
    private Service6 service;
    public Thread3(Service6 service){
        super();
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printC();
    }
}

  run:

package test;

import extthread.Thread1;
import extthread.Thread2;
import extthread.Thread3;
import service.Service6;

/**
 * Created by zhc on 2017/10/10
 */
public class Run6 {
    public static void main(String[] args) {
        Service6 service = new Service6();
        Thread1 t1 = new Thread1(service);
        t1.setName("A");
        t1.start();
        Thread2 t2 = new Thread2(service);
        t2.setName("B");
        t2.start();
        Thread3 t3 = new Thread3(service);
        t3.setName("C");
        t3.start();

    }
}

  结果:

  线程A在 1507622252932进入printA
  线程C在 1507622252932进入printC
  线程C在 1507622252932离开printC
  线程A在 1507622255937离开printA
  线程B在 1507622255937进入printB
  线程B在 1507622255937离开printB

  总结:前四行可以看出,线程C、线程A异步执行,因为两个方法的锁不是一个锁。通过观察方法A、B可以看出来A、B还是相同的锁,所以就算A等了三秒B还是要等A执行完再执行。

 

  

posted on 2017-10-10 16:09  汉成  阅读(590)  评论(0)    收藏  举报

导航