在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。
如图,synchronized可以用在方法上也可以使用在代码块中,其中方法是实例方法和静态方法分别锁的是该类的实例对象和该类的对象。而使用在代码块中也可以分为三种,具体的可以看上面的表格。
这里的需要注意的是:如果锁的是类对象的话,尽管new多个实例对象,但他们仍然是属于同一个类依然会被锁住,即线程之间保证同步关系。
修饰一个代码块
1.一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞。 synchronized(this)锁的是对象
public class SyncThread implements Runnable { private static int count; public SyncThread() { count = 0; } @Override public void run() { synchronized (this) { for (int i = 0; i < 5; i++) { try { System.out.println(Thread.currentThread().getName() + ":" + (count++)); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { final SyncThread syncThread = new SyncThread(); //两个线程同一个对象互斥。两个线程同两个对象不互斥跑同一个方法。 Thread thread1 = new Thread(syncThread, "SyncThread1"); Thread thread2 = new Thread(syncThread, "SyncThread2"); thread1.start(); thread2.start(); } }
结果:
SyncThread1:0 SyncThread1:1 SyncThread1:2 SyncThread1:3 SyncThread1:4 SyncThread2:5 SyncThread2:6 SyncThread2:7 SyncThread2:8 SyncThread2:9
2.一个线程访问一个对象中的synchronized(this)同步代码块时,另一个线程可以访问new新对象的synchronized(this)同步代码.
public class SyncThread implements Runnable { private static int count; public SyncThread() { count = 0; } @Override public void run() { synchronized (this) { for (int i = 0; i < 5; i++) { try { System.out.println(Thread.currentThread().getName() + ":" + (count++)); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { final SyncThread syncThread1 = new SyncThread(); final SyncThread syncThread2 = new SyncThread(); //两个线程同一个对象互斥。两个线程同两个对象不互斥跑同一个方法。 Thread thread1 = new Thread(syncThread1, "SyncThread1"); Thread thread2 = new Thread(syncThread2, "SyncThread2"); thread1.start(); thread2.start(); } }
结果:
SyncThread1:0 SyncThread2:1 SyncThread1:2 SyncThread2:3 SyncThread1:4 SyncThread2:5 SyncThread1:6 SyncThread2:7 SyncThread1:8 SyncThread2:9