1.修饰在方法上,多个线程调用同一个对象的同步方法会阻塞,调用不一样对象的同步方法不会阻塞。(java对象的内存地址是否相同)java
public synchronized void obj3() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } }
2.修饰代码块,这个this就是指当前对象(类的实例),多个线程调用同一个对象的同步方法会阻塞,调用不一样对象的同步方法不会阻塞。(java对象的内存地址是否相同)多线程
public void obj2() { synchronized (this) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
3.修饰代码块,这个str就是指String对象,多个线程调用同一个对象的同步方法会阻塞,调用不一样对象的同步方法不会阻塞。(java对象的内存地址是否相同)ide
public void obj2() { String str=new String("lock");//在方法体内,调用一次就实例化一次,多线程访问不会阻塞,由于不是同一个对象,锁是不一样的 synchronized (str) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
public static void main(String[] args) throws InterruptedException { test test=new test(); new Thread(new Runnable() { @Override public void run() { test.obj2(); } }).start(); new Thread(new Runnable() { @Override public void run() { test.obj2(); } }).start(); }
//两个方法之间交替执行 没有阻塞
Thread-0 : 4
Thread-1 : 4
Thread-1 : 3
Thread-0 : 3
Thread-1 : 2
Thread-0 : 2
Thread-1 : 1
Thread-0 : 1
Thread-0 : 0
Thread-1 : 0
共用一个对象,多线程调用obj2同步方法,由于使用的是一个对象锁,会阻塞。this
String str=new String("lock"); //对象放在方法外,调用方法的时候不会新建立一个对象。 public void obj2() { synchronized (str) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
Thread-0 : 4
Thread-0 : 3
Thread-0 : 2
Thread-0 : 1
Thread-0 : 0
Thread-1 : 4
Thread-1 : 3
Thread-1 : 2
Thread-1 : 1
Thread-1 : 0
1.Synchronized修饰静态的方法spa
public static synchronized void obj3() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } }
2.synchronized (test.class) ,锁的对象是test.class,即test类的锁。线程
public void obj1() { synchronized (test.class) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
那么问题来了:在一个类中有两方法,分别用synchronized 修饰的静态方法(类锁)和非静态方法(对象锁)。多线程访问两个方法的时候,线程会不会阻塞?code
public static synchronized void obj3() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public synchronized void obj4() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } }
答案是???对象
Thread-0 : 4
Thread-1 : 4
Thread-0 : 3
Thread-1 : 3
Thread-1 : 2
Thread-0 : 2
Thread-1 : 1
Thread-0 : 1
Thread-1 : 0
Thread-0 : 0blog
到这么咱们应该知道了:内存
1,要知足方法同步(或者代码块同步)就必须保证多线程访问的是同一个对象(在java内存中的地址是否相同)。
2,类锁和对象锁同时存在时,多线程访问时不会阻塞,由于他们不是一个锁。
----------------------------------------------------------------------------------------------------------------
理解不到位的地方,烦请指出来。