静态同步synchronized方法与synchronized(class)代码块

一.关键字synchronized可以运用在静态方法上,如果这样写,那就是对当前的*.java文件对应的Class类进行持锁。

而非静态方法是给对象上锁,本质是不一样的。

二.验证案例

1)案例一:区分静态方法和非静态案例:

package org.zhq.test;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-13 下午1:52:21
 * 类说明
 */
public class Service {
	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 (Exception e) {
			e.printStackTrace();
		}
	}
	synchronized public static void printB(){
		try {
			System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printB");
			System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printB");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	synchronized public void printC(){
		try {
			System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printC");
			System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printC");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
package org.zhq.test;
/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-13 上午11:33:08
 * 类说明
 */
public class ThreadA extends Thread {
	private Service service;
	public ThreadA( Service service){
		super();
		this.service=service;
	}
	@Override
	synchronized public void run() {
		service.printA();
	}
	
}
package org.zhq.test;
/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-13 上午11:33:36
 * 类说明
 */
public class ThreadB extends Thread {
	private Service service;
	public ThreadB( Service service){
		super();
		this.service=service;
	}
	@Override
	synchronized public void run() {
		service.printB();
	}
}
package org.zhq.test;
/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-14 上午9:03:32
 * 类说明
 */
public class ThreadC extends Thread{
	private Service service;
	public ThreadC( Service service){
		super();
		this.service=service;
	}
	@Override
	synchronized public void run() {
		service.printC();
	}
}
package org.zhq.test;
/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-11 下午3:02:47
 * 类说明
 */
public class Run {

	public static void main(String[] args) throws InterruptedException {
		Service service=new Service();
		ThreadA a=new ThreadA(service);
		a.setName("A");
		a.start();
		ThreadB b=new ThreadB(service);
		b.setName("B");
		b.start();
		ThreadC c=new ThreadC(service);
		c.setName("C");
		c.start();
	}	

}

结果:A和C异步的原因是持有不同的锁,一个时对象锁,一个是class锁,而Class锁可以对类的所有对象实例起作用。


2)案例二:静态方法对所有的实例起作用:

package org.zhq.test;
/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-11 下午3:02:47
 * 类说明
 */
public class Run {

	public static void main(String[] args) throws InterruptedException {
		Service service_1=new Service();
		Service service_2=new Service();
		ThreadA a=new ThreadA(service_1);
		a.setName("A");
		a.start();
		ThreadB b=new ThreadB(service_2);
		b.setName("B");
		b.start();
	}	

}

结果:虽然不是同一对象,但是同步锁同样起作用。


3)案例三:synchronized(class)代码块对所有的实例起作用:

修改service代码

package org.zhq.test;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-13 下午1:52:21
 * 类说明
 */
public class Service {
	public static void printA(){
		synchronized (Service.class) {
			try {
				System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printA");
				Thread.sleep(3000);
				System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printA");
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	public static void printB(){
		synchronized (Service.class) {
			try {
				System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printB");
				System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printB");
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	synchronized public void printC(){
		try {
			System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printC");
			System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printC");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

再次运行run

package org.zhq.test;
/**
 * @author 作者 hq.zheng:
 * @version 创建时间:2018-6-11 下午3:02:47
 * 类说明
 */
public class Run {

	public static void main(String[] args) throws InterruptedException {
		Service service_1=new Service();
		Service service_2=new Service();
		ThreadA a=new ThreadA(service_1);
		a.setName("A");
		a.start();
		ThreadB b=new ThreadB(service_2);
		b.setName("B");
		b.start();
	}	

}

结果:跟静态方法效果一致。




阅读更多
文章标签: 静态同步 class锁
个人分类: 多线程
上一篇解决 response.addHeader中文乱码
下一篇多线程死锁
想对作者说点什么? 我来说一句

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

关闭
关闭
关闭