首页 > 其他 > 详细

java线程之——synchronized的注意细节

时间:2014-03-12 16:02:54      阅读:377      评论:0      收藏:0      [点我收藏+]

  我在学习synchronized的时候,十分好奇当一个线程进入了一个对象的一个synchronized普通方法后,其它线程是否可进入此对象的其它方法?

  然后就做了个实验(实验代码最后贴出),最后得到了如下结论:

  1)其它方法是加了synchronized的普通方法,不能;

  2)其它方法是没加synchronized的普通方法,能;

  3)其它方法是synchronizedstatic方法,能;

  4)其它方法是没加synchronizedstatic方法,能。

 

  当一个线程进入了一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法:

  1)其它方法是加了synchronized的普通方法,能;

  2)其它方法是没加synchronized的普通方法,能;

  3)其它方法是synchronizedstatic方法,不能;

  4)其它方法中有synchronized(xxx.class)的,不能;

  5)其它方法是没加synchronizedstatic方法,能。

 

  其实只要明白了普通方法加synchronized的本质是给对象的this加了对象锁,上面的结论就不难理解了,

  其中不管static方法是否加synchroized,只要锁的是this,即当前对象,而不是当前类(XXX.class),就可以执行;

  而给当前类加锁时,除了同步的static方法不能调用外,其它的都可以。

  

  实验代码如下:

package javaBase;

public class JB_052_Synchronized {
	public static void main(String[] args) {
		Resource_052 rs = new Resource_052();
		
		Thread t1 = new Thread(new Thread1_052(rs));  //调用synchronized方法的线程
		Thread t0 = new Thread(new Thread0_052(rs));  //调用普通方法的线程
		Thread t2 = new Thread(new Thread2_052(rs));  //调用另一个synchronized方法的线程
		Thread t3 = new Thread(new Thread3_052(rs));  //调用synchronized static 方法的线程
		Thread t4 = new Thread(new Thread4_052(rs));  //调用static方法的线程
		
		Thread t5 = new Thread(new Thread5_052(rs));  //调用锁class方法的线程
		
		t1.start();  //调用了synchronized方法
		try{
			System.out.println("调用synchronized方法的thread1启动后主程序等待2秒,确保在其它线程执行之前thread1获得对象锁");
			Thread.sleep(2000);
		}catch(InterruptedException e){
			e.printStackTrace();
		}
		t0.start();   //调用了普通方法  //可以 
		t2.start();   //调用了另一个synchronized方法   //不行
		t3.start();   //调用了synchronized static 方法  //可以
		t4.start();  //调用了static方法   //可以
		
		
		//锁class
		try{
			System.out.println("主程序等待10秒,等前面的线程除thread1和被阻塞的线程外都执行完成,后面的代码将做锁class测试....");
			Thread.sleep(10000);
			System.out.println("10秒等待完。");
		}catch(InterruptedException e){
			e.printStackTrace();
		}
		//thread5中会置flag=false终止thread1
		t5.start();
		try{
			System.out.println("主程序等待10秒,确保thread5获得class的对象锁,确保thread1和被阻塞的线程都终止。");
			Thread.sleep(10000);
			System.out.println("10秒等待完。");
		}catch(InterruptedException e){
			e.printStackTrace();
		}
		 
		t0 = new Thread(new Thread0_052(rs));  //普通方法
		t2 = new Thread(new Thread2_052(rs));  //另一个synchronized方法
		t3 = new Thread(new Thread3_052(rs));  //synchronized static 方法
		t4 = new Thread(new Thread4_052(rs));  //static方法
		
		t0.start();   //调用了普通方法  //可以 
		t2.start();   //调用了另一个synchronized方法   //不行
		t3.start();   //调用了synchronized static 方法  //不可以
		t4.start();  //调用了static方法   //可以
	}
}


class Resource_052{
	public boolean flag = true;
	
	public void method0(){
		System.out.println("this is a ordinary method——method0.");
	}
	synchronized public void method1(){
		while(flag){
			System.out.println("this is a synchronized method——method1.");
			try{
				Thread.sleep(2000);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
	synchronized public void method2(){
		System.out.println("this is the second synchronized method——method2.");
	}
	synchronized public static void method3(){
		System.out.println("this is a  synchronized static method——method3.");
	}
	public static void method4(){
		System.out.println("this is a  ordinary static method——method4.");
	}
	
	public void method5(){
		synchronized(Resource_052.class){
			while(true){
				System.out.println("this is a  synchronized static method——method5.");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			}
	}
	
	synchronized public static void method6(){   //与method5等价
		while(true){
			System.out.println("this is a  synchronized static method——method6.");
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}

class Thread1_052 implements Runnable{
	private Resource_052 rs;
	/**
	 * constructor
	 * @param rs
	 */
	public Thread1_052(Resource_052 rs){
		this.rs = rs;
	}
	@Override
	public void run(){
		this.rs.method1();  //调用synchronized方法
	}
}
class Thread0_052 implements Runnable{
	private Resource_052 rs;
	/**
	 * constructor
	 * @param rs
	 */
	public Thread0_052(Resource_052 rs){
		this.rs = rs;
	}
	@Override
	public void run(){
		this.rs.method0();  //调用普通方法
	}
}
class Thread2_052 implements Runnable{
	private Resource_052 rs;
	/**
	 * constructor
	 * @param rs
	 */
	public Thread2_052(Resource_052 rs){
		this.rs = rs;
	}
	@Override
	public void run(){
		this.rs.method2();  //调用另一个synchronized方法
	}
}
class Thread3_052 implements Runnable{
	private Resource_052 rs;
	/**
	 * constructor
	 * @param rs
	 */
	public Thread3_052(Resource_052 rs){
		this.rs = rs;
	}
	@Override
	public void run(){
		this.rs.method3();  //调用synchronized static方法
	}
}
class Thread4_052 implements Runnable{
	private Resource_052 rs;
	/**
	 * constructor
	 * @param rs
	 */
	public Thread4_052(Resource_052 rs){
		this.rs = rs;
	}
	@Override
	public void run(){
		this.rs.method4();  //调用普通static方法
	}
}
class Thread5_052 implements Runnable{
	private Resource_052 rs;
	/**
	 * constructor
	 * @param rs
	 */
	public Thread5_052(Resource_052 rs){
		this.rs = rs;
	}
	@Override
	public void run(){
		rs.flag=false;
		this.rs.method5();  //调用锁Class的方法
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

  得到的结果如下:

==================================================================================================

调用synchronized方法的thread1启动后主程序等待2秒,确保在其它线程执行之前thread1获得对象锁
this is a synchronized method——method1.
this is a synchronized method——method1.
主程序等待10秒,等前面的线程除thread1和被阻塞的线程外都执行完成,后面的代码将做锁class测试....
this is a ordinary method——method0.
this is a synchronized static method——method3.
this is a ordinary static method——method4.      //从这里的结果可以看到synchronized 普通方法method3没有执行
this is a synchronized method——method1.
this is a synchronized method——method1.
this is a synchronized method——method1.
this is a synchronized method——method1.
10秒等待完。
主程序等待10秒,确保thread5获得class的对象锁,确保thread1和被阻塞的线程都终止。
this is a synchronized static method——method5.
this is the second synchronized method——method2.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
10秒等待完。
this is a ordinary method——method0.
this is a ordinary static method——method4.
this is the second synchronized method——method2.  //可以看到synchronized static方法method3没有执行
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.


==================================================================================================

java线程之——synchronized的注意细节,布布扣,bubuko.com

java线程之——synchronized的注意细节

原文:http://www.cnblogs.com/chrischennx/p/3594360.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!