java多线程学习(四)

本篇介绍synchronized(非this对象x)方式的同步,x一般是参数或者实例变量

不同线程持有不同的对象监视器,调用是异步的

package chapter2.synBlockString3;

/*演示不同线程持有不同的对象监视器,调用是异步的
 * ta的对象监视器是anyString,而b的对象监视器是类实例对象
a begin
b begin
b end
a end
 */
public class Run {

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

}
package chapter2.synBlockString3;

public class Service {
	private String anyString=new String();
	public void a(){
		try{
			synchronized (anyString) {
				System.out.println("a begin");
				Thread.sleep(3000);
				System.out.println("a end");
			}
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
	synchronized public void b(){
		System.out.println("b begin");
		System.out.println("b end");
	}
}
package chapter2.synBlockString3;

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

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

synchronized(非this对象x)用法的三个结论:

1,当多个对象同时执行synchronized(x){}同步代码块时呈同步效果

2,当其他对象执行x对象的synchronized方法时呈现同步效果,但如果其他线程调用x对象的非synchronized方法还是异步的

3,当其他对象执行x对象里的synchronized(this)代码块时也是同步的

前两条结论比较明显,仅仅验证第三条结论:

package chapter2.test3;

public class MyObject {
	public void speedPrintString(){
		synchronized (this) {
			System.out.println("speedPrintString __get locked time="+System.currentTimeMillis()+
					"run thread name="+Thread.currentThread().getName());
			System.out.println("------------------");
			System.out.println("speedPrintString ___release locked time="+System.currentTimeMillis()+
					"run thread name="+Thread.currentThread().getName());
		}
	}
}
package chapter2.test3;
/*演示当使用syn(obj)方式时,其他进程进入obj的syn(this)代码块是同步的,因为syn(this)也是对obj实例加锁
 * 也就是b线程需要等待a线程执行完syn(obj),释放obj的锁,才能获得obj的锁,
testMethod1 _____get locked time=1525528023801run threadName=a
testMethod1 _____release locked time=1525528025801run threadName=a
speedPrintString __get locked time=1525528025801run thread name=b
------------------
speedPrintString ___release locked time=1525528025802run thread name=b

 */
public class Run {

	public static void main(String[] args) throws InterruptedException {
		Service sv=new Service();
		MyObject mo=new MyObject();
		ThreadA ta=new ThreadA(mo, sv);
		ThreadB tb=new ThreadB(mo);
		ta.setName("a");
		ta.start();
		//这里将main线程睡眠是为了让a线程先进入同步块
		Thread.sleep(100);
		tb.setName("b");
		tb.start();
	}

}
package chapter2.test3;

public class Service {
	public void testMethod1(MyObject obj){
		synchronized (obj) {
			try{
				System.out.println("testMethod1 _____get locked time="+System.currentTimeMillis()+
						"run threadName="+Thread.currentThread().getName());
				Thread.sleep(2000);
				System.out.println("testMethod1 _____release locked time="+System.currentTimeMillis()+
						"run threadName="+Thread.currentThread().getName());
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
}
package chapter2.test3;

public class ThreadA extends Thread {
	private MyObject obj;
	private Service sv;
	public ThreadA(MyObject obj,Service sv) {
		super();
		this.obj=obj;
		this.sv=sv;
	}
	@Override
	public void run() {
		super.run();
		sv.testMethod1(obj);
	}
}
package chapter2.test3;

public class ThreadB extends Thread {
	private MyObject obj;
	public ThreadB(MyObject obj) {
		super();
		this.obj=obj;
	}
	@Override
	public void run() {
		super.run();
		//调用obj的syn方法
		obj.speedPrintString();
	}
}

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

猜你喜欢

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