简介
说明
本文用示例介绍synchronized的用法。
作用
synchronized可以保证原子性、可见性。
只要保证线程使用同一个“对象监视锁”,就能保证同步。
用法简介
用法 | 对象监视器 | 示例 |
修饰普通方法 | 当前实例对象 | public synchronized void increase() {i++; } |
修饰静态方法 | 当前类的class对象 | public static synchronized void increase() { i++; } |
修饰代码块 | 括号里边的对象。 此对象可以是实例对象(例:this),也可以是class对象(例:XXX.class或者this.getClass())。 | public Object increase(Object a1) { synchronized(a1) { // 操作 }} |
例:修饰普通方法,用同一对象访问
package org.example.a; class MyThread implements Runnable{ @Override public synchronized void run() { System.out.println(1); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(2); } } public class Demo{ public static void main(String[] args) { MyThread myThread = new MyThread(); Thread thread1 = new Thread(myThread); Thread thread2 = new Thread(myThread); thread1.start(); thread2.start(); } }
执行结果(结果同步,因为synchronized修饰普通方法时锁对象是this对象,使用一个对象去访问,是同一把锁。)
1 2 1 2
例:修饰普通方法,用不同对象访问
package org.example.a; class MyThread implements Runnable{ @Override public synchronized void run() { System.out.println(1); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(2); } } public class Demo{ public static void main(String[] args) { MyThread myThread1 = new MyThread(); Thread thread1 = new Thread(myThread1); MyThread myThread2 = new MyThread(); Thread thread2 = new Thread(myThread2); thread1.start(); thread2.start(); } }
执行结果(结果不同步,因为synchronized修饰普通方法时锁对象是this对象,使用两个对象去访问,不是同一把锁。)
1 1 2 2
例:修饰Class对象,用不同对象访问
package org.example.a; class MyThread implements Runnable{ @Override public void run() { synchronized (MyThread.class) { System.out.println(1); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(2); } } } public class Demo{ public static void main(String[] args) { MyThread myThread1 = new MyThread(); Thread thread1 = new Thread(myThread1); MyThread myThread2 = new MyThread(); Thread thread2 = new Thread(myThread2); thread1.start(); thread2.start(); } }
执行结果(结果同步,因为synchronized修饰的是一个类对象,是惟一的。)
1 2 1 2
例:修饰静态方法,用不同对象访问
本处不能这样写:
class MyThread implements Runnable{ @Override public static synchronized void run() { System.out.println(1); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(2); } }
会报错。因为Runnable接口的run方法是非静态类型,此处若使用静态,会提示没有覆写run方法。
请先
!