java多线程学习(五)

本篇主要介绍synchronized静态方法和synchronized(class)的使用

1,静态同步方法的锁对象是class不同于静态同步方法的锁对象是类实例

package chapter2.synTwoLock;
/*
演示静态方法锁对象和非静态方法锁对象不是同一个锁,
从结果来看ac是异步的,a,b是同步的,因为printa和printb都是静态同步方法,二者锁对象都是class
而printC是非静态的同步方法,锁对象是类实例,和a,b不是一个对象监视器,是异步调用的
线程名称为:a 在 1525529667507 进入printA
线程名称为:c 在 1525529667509 进入printC
线程名称为:c 在 1525529667509 离开printC
线程名称为:a 在 1525529670508 离开printA
线程名称为:b 在 1525529670509 进入printB
线程名称为:b 在 1525529670509 离开printB
 */
public class Run {

	public static void main(String[] args) {
		Service service=new Service();
		ThreadA ta=new ThreadA(service);
		ta.setName("a");
		ta.start();
		ThreadB tb=new ThreadB(service);
		tb.setName("b");
		tb.start();
		ThreadC tc=new ThreadC(service);
		tc.setName("c");
		tc.start();
	}

}
package chapter2.synTwoLock;

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 (InterruptedException e) {
			// TODO Auto-generated catch block
			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 chapter2.synTwoLock;

public class ThreadA extends Thread {
	private Service service;
	public ThreadA(Service service) {
		super();
		this.service=service;
	}
	@Override
	public void run() {
		super.run();
		service.printA();
	}
}
package chapter2.synTwoLock;

public class ThreadB extends Thread {
	private Service service;
	public ThreadB(Service service) {
		super();
		this.service=service;
	}
	@Override
	public void run() {
		super.run();
		service.printB();
	}
}
package chapter2.synTwoLock;

public class ThreadC extends Thread {
	private Service service;
	public ThreadC(Service service) {
		super();
		this.service=service;
	}
	@Override
	public void run() {
		super.run();
		service.printC();
	}
}

2,Class锁可以对类的所有实例起作用

package chapter2.synMoreObjectStaticOneLock;
/*演示静态同步方法,对不同类实例的同步效果,也就是Class锁可以对类的所有实例起作用
 * a,b线程的service实例是两个不同的对象,但结果是b线程等待a线程结束才会进入静态同步方法,
 * 如果是非静态的同步方法,不同实例的调用是异步的,这里注意区分
线程名称为:a 在 1525529960193 进入printA
线程名称为:a 在 1525529963193 离开printA //这里等待3s
线程名称为:b 在 1525529963193 进入printB
线程名称为:b 在 1525529963193 离开printB
 */
public class Run {

	public static void main(String[] args) {
		Service service1=new Service();
		Service service2=new Service();
		ThreadA ta=new ThreadA(service1);
		ta.setName("a");
		ta.start();
		ThreadB tb=new ThreadB(service2);
		tb.setName("b");
		tb.start();
	}

}
package chapter2.synMoreObjectStaticOneLock;

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 (InterruptedException e) {
			// TODO Auto-generated catch block
			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");
	}
}
package chapter2.synMoreObjectStaticOneLock;

public class ThreadA extends Thread {
	private Service service;
	public ThreadA(Service service) {
		super();
		this.service=service;
	}
	@Override
	public void run() {
		super.run();
		service.printA();
	}
}
package chapter2.synMoreObjectStaticOneLock;

public class ThreadB extends Thread {
	private Service service;
	public ThreadB(Service service) {
		super();
		this.service=service;
	}
	@Override
	public void run() {
		super.run();
		service.printB();
	}
}

3,synchronized(class)

静态方法的synchronized(class)代码块和静态同步方法效果相同

package chapter2.synBlockMoreObjectOneLock;

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 (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

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

}
package chapter2.synBlockMoreObjectOneLock;
/*演示静态方法的synchronized(class)代码块和静态同步方法效果相同
线程名称为:a 在 1525530881142 进入printA
线程名称为:a 在 1525530884143 离开printA
线程名称为:b 在 1525530884143 进入printB
线程名称为:b 在 1525530884144 离开printB
 */
public class Run {

	public static void main(String[] args) {
		Service service1=new Service();
		Service service2=new Service();
		ThreadA ta=new ThreadA(service1);
		ta.setName("a");
		ta.start();
		ThreadB tb=new ThreadB(service2);
		tb.setName("b");
		tb.start();
	}

}
package chapter2.synBlockMoreObjectOneLock;

public class ThreadA extends Thread {
	private Service service;
	public ThreadA(Service service) {
		super();
		this.service=service;
	}
	@Override
	public void run() {
		super.run();
		service.printA();
	}
}
package chapter2.synBlockMoreObjectOneLock;

public class ThreadB extends Thread {
	private Service service;
	public ThreadB(Service service) {
		super();
		this.service=service;
	}
	@Override
	public void run() {
		super.run();
		service.printB();
	}
}

参考:<java多线程编程核心技术>

猜你喜欢

转载自blog.csdn.net/qq467215628/article/details/80210050