Synchronized的两种用法

时间:2019-01-18
本文章向大家介绍Synchronized的两种用法,主要包括Synchronized的两种用法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.对象锁

  • 方法锁(默认锁对象为this当前实例对象)
public class Demo3 implements Runnable{
	static Demo3 demo2=new Demo3();

	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Thread t1=new Thread(demo2);
       Thread t2=new Thread(demo2);
       t1.start();
       t2.start();
       while(t1.isAlive()||t2.isAlive()) {
    	   
       }
       System.out.println("finished");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		method();
	}
	public synchronized void method() {
		synchronized(this) {
			 
			System.out.println("现在是对象方法锁的形式:"+Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"已经运行结束");
		}
	}
}

public class Demo2 implements Runnable{
	static Demo2 demo2=new Demo2();
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Thread t1=new Thread(demo2);
       Thread t2=new Thread(demo2);
       t1.start();
       t2.start();
       while(t1.isAlive()||t2.isAlive()) {
    	   
       }
       System.out.println("finished");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized(this) {
		System.out.println("现在是对象锁形式:"+Thread.currentThread().getName());
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"已经运行结束");
	}
		
	}
}

运行结果:
现在是对象方法锁的形式:Thread-0
Thread-0已经运行结束
现在是对象方法锁的形式:Thread-1
Thread-1已经运行结束
finished

  • 同步代码块
public class Demo2 implements Runnable{
	static Demo2 demo2=new Demo2();
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Thread t1=new Thread(demo2);
       Thread t2=new Thread(demo2);
       t1.start();
       t2.start();
       while(t1.isAlive()||t2.isAlive()) {
    	   
       }
       System.out.println("finished");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized(this) {
		System.out.println("现在是对象锁形式:"+Thread.currentThread().getName());
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"已经运行结束");
	}
		
	}
}

运行结果:

public class Demo2 implements Runnable{
	static Demo2 demo2=new Demo2();
	Object object1=new Object();
	Object object2=new Object();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Thread t1=new Thread(demo2);
       Thread t2=new Thread(demo2);
       t1.start();
       t2.start();
       while(t1.isAlive()||t2.isAlive()) {
    	   
       }
       System.out.println("finished");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized(object1) {
			 
			System.out.println("现在是object1:"+Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"object1已经运行结束");
		}
			synchronized(object1) {
				System.out.println("现在是object2:"+Thread.currentThread().getName());
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"object2已经运行结束");
			}
	}
}

两个同步代码块锁定是同一个实例,运行结果;
现在是object1:Thread-0
Thread-0object1已经运行结束
现在是object1:Thread-1
Thread-1object1已经运行结束
现在是object2:Thread-1
Thread-1object2已经运行结束
现在是object2:Thread-0
Thread-0object2已经运行结束
finished

public class Demo2 implements Runnable{
	static Demo2 demo2=new Demo2();
	Object object1=new Object();
	Object object2=new Object();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Thread t1=new Thread(demo2);
       Thread t2=new Thread(demo2);
       t1.start();
       t2.start();
       while(t1.isAlive()||t2.isAlive()) {
    	   
       }
       System.out.println("finished");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized(object1) {
			 
			System.out.println("现在是object1:"+Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"object1已经运行结束");
		}
			synchronized(object2) {
				System.out.println("现在是object2:"+Thread.currentThread().getName());
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"object2已经运行结束");
			}
	}
}



两个同步代码块锁定是不同实例,运行结果:
现在是object1:Thread-0
Thread-0object1已经运行结束
现在是object1:Thread-1
现在是object2:Thread-0

Thread-0object2已经运行结束
Thread-1object1已经运行结束
现在是object2:Thread-1
Thread-1object2已经运行结束
finished

总结:
代码块形式:手动指定锁对象
方发锁形式:Synchronized修饰普通方法,锁对象默认为this.

2.类锁
概念

  • 只有一个class对象:java类可能会有很多个对象,但只有一个类对象。
  • 本质:所谓的类锁,不过是class对象的锁而已。
  • 用法和效果:类锁在同一时刻只能被一个对象拥有。

两种形式

  1. Synchronized修饰静态的方法
public class Demo4 implements Runnable{
	static Demo4 demo2=new Demo4();
	static Demo4 demo3=new Demo4();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Thread t1=new Thread(demo2);
       Thread t2=new Thread(demo3);
       t1.start();
       t2.start();
       while(t1.isAlive()||t2.isAlive()) {
    	   
       }
       System.out.println("finished");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		method();
	}
	public **static** synchronized void method() {
		
			 
			System.out.println("现在是对象方法锁的形式:"+Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"已经运行结束");
		}
	
}

运行结果:
现在是对象方法锁的形式:Thread-0
Thread-0已经运行结束
现在是对象方法锁的形式:Thread-1
Thread-1已经运行结束
finished
2. 指定锁为class对象

public class Demo5 implements Runnable{
	static Demo5 demo2=new Demo5();
	static Demo5 demo3=new Demo5();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Thread t1=new Thread(demo2);
       Thread t2=new Thread(demo3);
       t1.start();
       t2.start();
       while(t1.isAlive()||t2.isAlive()) {
    	   
       }
       System.out.println("finished");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		method();
	}
	private void method() {
		
			 synchronized (Demo5.class) {
				 System.out.println(Thread.currentThread().getName());
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"已经运行结束");
			}
			
		}
	
}

运行结果:
Thread-0已经运行结束
现在是对象方法锁的形式:Thread-1
Thread-1已经运行结束
finished