java 线程锁 一些用法和总结

1,锁重用,如果一个方法用synchronized修饰,并且这个方法中引入了其他的用synchronized修饰的方法,那么线程执行这个方法的时候,会自动获取方法中的其他方法锁。

例子:

public class SynchronzedClass {
	public  synchronized void a(){
		b();
	}
	public  synchronized void b(){
		System.out.println("b method");
	} 
}

public class SynMainClass {
	public static void main(String[] args) {
		Thread t = new Thread();
		final SynchronzedClass syb = new SynchronzedClass();
		Thread t1 = new Thread(new Runnable() {	
			@Override
			public void run() {
				syb.a();
			}
		});
		t1.start();
	}
}

结果:b method

2,同步不具有继承性

例子:

public class FatherClass {
	public synchronized void a(){
		try {
			System.out.println("father begin :"+Thread.currentThread().getName());
			Thread.sleep(5000);
			System.out.println("father end :"+Thread.currentThread().getName());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	
	
	private class SunClass extends FatherClass{
		@Override
		public void a() {
			try {
				System.out.println("son begin:"+Thread.currentThread().getName());
				Thread.sleep(5000);
				System.out.println("son end:"+Thread.currentThread().getName());
				super.a();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	private class Thread1 extends Thread{
		private SunClass sunClass;
		public Thread1(SunClass sunClass){
			this.sunClass = sunClass;
		}
		
		@Override
		public void run() {
			sunClass.a();
			super.run();
		}
	}
	
	
	private class Thread2 extends Thread{
		private SunClass sunClass;
		public Thread2(SunClass sunClass){
			this.sunClass = sunClass;
		}
		
		@Override
		public void run() {
			sunClass.a();
			super.run();
		}
	}
	
	public static void main(String[] args) {
		FatherClass f = new FatherClass();
		SunClass son = f.new SunClass();
		Thread1 t1 = f.new Thread1(son);
		Thread2 t2 = f.new Thread2(son);
		t1.setName("a");
		t2.setName("b");
		t1.start();
		t2.start();
	}
}

结果:son begin:a
      son begin:b
      son end:b
      son end:a
     father begin :b
     father end :b
     father begin :a
     father end :a
     
可以看到子类继承的方法在多线程的情况下是不同步的,但是他们的父类被继承的方法是同步的,这个例子是
用内部类的方法实现的,此规则在非内部类情况下依然适用。

3,当一个线程出现异常的时候,会释放他所持有的锁

public class ExceptionThread {
	private class Demo{
		private int a=0;
		public synchronized void test(){
			if(Thread.currentThread().getName().equals("a")){
				System.out.println(12/a);
			}else{
				System.out.println("b method");
			}
		}
	}
	private class Thread1 extends Thread{
		private Demo e;
		Thread1(Demo e){
			this.e = e;
		}
		
		@Override
		public void run() {
			e.test();
			super.run();
		}
	}
	private class Thread2 extends Thread{
		private Demo e;
		Thread2(Demo e){
			this.e = e;
		}
		@Override
		public void run() {
			e.test();
			super.run();
		}
	}
	public static void main(String[] args) {
		ExceptionThread e = new ExceptionThread();
		Demo d = e.new Demo();
		Thread1 t1 = e.new Thread1(d);
		Thread2 t2 = e.new Thread2(d);
		t1.setName("a");
		t2.setName("b");
		t1.start();
		t2.start();
	}
}

结果:Exception in thread "a" b method
java.lang.ArithmeticException: / by zero
	at com.qsfs.thread.synch.use.ExceptionThread$Demo.test(ExceptionThread.java:8)
	at com.qsfs.thread.synch.use.ExceptionThread$Thread1.run(ExceptionThread.java:22)

4,(1)synchronized 方法()与synchronized(this){}等效的 ,锁的都是对象

public class ThisThread {
	public void test(){
		synchronized(this){
			try {
				System.out.println("begin"+Thread.currentThread().getName());
				Thread.sleep(3000);
				System.out.println("begin"+Thread.currentThread().getName());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
	
	private class Thread1 extends Thread{
		private ThisThread e;
		Thread1(ThisThread e){
			this.e = e;
		}
		
		@Override
		public void run() {
			e.test();
			super.run();
		}
	}
	private class Thread2 extends Thread{
		private ThisThread e;
		Thread2(ThisThread e){
			this.e = e;
		}
		@Override
		public void run() {
			e.test();
			super.run();
		}
	}
	
	
	
	public static void main(String[] args) {
		ThisThread d = new ThisThread();
		ThisThread d1 = new ThisThread();
		Thread1 t1 = d.new Thread1(d);
		Thread2 t2 = d.new Thread2(d1);
		t1.setName("a");
		t2.setName("b");
		t1.start();
		t2.start();
	}
}

     (2)synchronized static 方法()与syncjronized(类.class)等效的,锁的都是类,此类生成的对象都会被锁住(方法,或者相同的钥匙)   

public class ClassSynchronizedThread {
	private synchronized static void test1() throws InterruptedException{
		System.out.println("begin method Synchronized"+Thread.currentThread().getName());
		Thread.sleep(3000);
		System.out.println("end method Synchronized"+Thread.currentThread().getName());
	}
	private void test2() throws InterruptedException{
		synchronized(ClassSynchronizedThread.class){
			System.out.println("begin synchronized block"+Thread.currentThread().getName());
			Thread.sleep(3000);
			System.out.println("end synchronized block"+Thread.currentThread().getName());
		}
	}
	private class Thread1 extends Thread{
		private ClassSynchronizedThread e;
		Thread1(ClassSynchronizedThread e){
			this.e = e;
		}
		@Override
		public void run() {
			try {
				e.test1();
				e.test2();
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			super.run();
		}
	}
	private class Thread2 extends Thread{
		private ClassSynchronizedThread e;
		Thread2(ClassSynchronizedThread e){
			this.e = e;
		}
		@Override
		public void run() {
			try {
				e.test1();
				e.test2();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			super.run();
		}
	}
	public static void main(String[] args) {
		ClassSynchronizedThread d1 = new ClassSynchronizedThread();
		ClassSynchronizedThread d2 = new ClassSynchronizedThread();
		Thread1 t1 = d1.new Thread1(d1);
		Thread2 t2 = d1.new Thread2(d2);
		t1.setName("a");
		t2.setName("b");
		t1.start();
		t2.start();
	}
}

5,一个类中可能有很多个内部类,这些类中很有可能就会有一些霸道的,比如一个内部类中方法的锁的对象可能就是其他内部类的对象,那么访问这个方法的线程与访问这个对象中静态方法的线程是同步执行的

    public class objec {
	 class A{
		private B b;
		private void test(B b){
			this.b = b;
			synchronized(b){
				for(int i=0;i<5;i++){
					System.out.println(Thread.currentThread().getName()+":"+i);
				}
			}
		}
	}
	
	
	 class B{
		public synchronized void test1(){
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+":"+i);
			}
			
		}
	}
	
	
	public static void main(String[] args) {
		objec o = new objec();
		final A a = o.new A();
		final B b = o.new B();
		
		
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				
				a.test(b);
			}
		},"a");
		
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				b.test1();
				
			}
		},"b");
		
		t1.start();
		t2.start();
	}
}

结果:
a:0
a:1
a:2
a:3
a:4
b:0
b:1
b:2
b:3
b:4
静态内部类和普通内部类都适用

6,synchronized(对象),如果对象不变,即使是属性变了,也不会影响效果

转载于:https://my.oschina.net/u/1169535/blog/652161

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值