一、对象锁与类锁。
synchronized关键字有四种实现方式,分为两大类,对象锁和类锁。
(1)对象锁:
对象锁,顾名思义是锁住对象,不同实例的锁互不影响。
1.synchronized关键字加在普通方法上。
2.synchronized(this)。
(2)类锁:
不管多少对象都共用同一把锁,同步执行,一个线程执行结束、其他的才能够调用同步的部分
1.synchronized关键字加在静态方法上类锁。
2.synchronized(类.class)。等同于(synchronized(object obj)里面是静态对象)
二、synchronized的理解。
1.synchronized(this)中:的this锁住的对象是传入new Thread(st)的st对象。this锁住当前对象。
解析:若同步代码块中进入一个new Thread(st)对象,则另一个new Thread(st)线程则进不去同步代码块,除非是传入的是new
Thread(st1或其他对象)就不会受影响。
2.synchronized(object
obj):obj被static修饰之后会锁定所有对象,因为被static修饰后,每个创建的该类对象实例的obj和a对象都是同一个。
注意:必须加static修饰,加了才会锁定所有对象,不加等同于synchronized (this)。
3.synchronized(类.class):都会锁住该类实例对象,因为锁住的是该类。
public class sellticket implements Runnable { private static int tickets=100;
//synchronized(obj)与synchronized(a)效果一样,因为被static修饰后,每个创建的该类对象实例的obj和a对象都是同一个。
private static Object obj=new Object(); //必须加static修饰,不加等同于synchronized (this)。
private static String a="ssss"; // private Object obj=null; public sellticket()
{ } @Override public void run() { while (true) { /* //任意选一个测试 synchronized
(this){ synchronized (obj){ synchronized (a){ synchronized (sellticket.class){
*/ if (tickets>0){ /* try { Thread.sleep(1000); } catch (InterruptedException
e) { e.printStackTrace(); } */
System.out.println(Thread.currentThread().getName()+"正在销售"+tickets+"张票");
tickets--; } } } public static void main(String[] args) { /*
//使用synchronized(this),则会锁不住这几个对象,因为st,st1,st2对象互不相同。
//使用synchronized(obj)与synchronized(a)会锁住这几个对象,因为被static修饰后,每个创建的该类对象实例的obj和a对象都是同一个。
//synchronized (sellticket.class),都会锁住该类实例对象,因为锁住的是该类。 sellticket st = new
sellticket(); sellticket st1 = new sellticket(); sellticket st2 = new
sellticket(); Thread t1 = new Thread(st, "窗口1"); Thread t2 = new Thread(st1,
"窗口2"); Thread t3 = new Thread(st2, "窗口3"); */
//使用synchronized(this),则会锁住这几个对象,因为都是st对象。
//使用synchronized(obj)与synchronized(a)会锁住这几个对象,因为被static修饰后,每个创建的该类对象实例的obj和a对象都是同一个。
//synchronized (sellticket.class),都会锁住该类实例对象,因为锁住的是该类。 sellticket st = new
sellticket(); Thread t1 = new Thread(st, "窗口1"); Thread t2 = new Thread(st,
"窗口2"); Thread t3 = new Thread(st, "窗口3"); t1.start(); t2.start(); t3.start();
} }