赞
踩
所以我们程序代码需要保证同一时刻有且只有一个线程在操作共享数据,而其他的线程必须等待该线程处理完数据后再对共享数据操作
synchronized符合互斥锁特性,特别注意,synchronized锁的不是代码,是对象
互斥性:即在同一时间只允许一个线程持有某个对象锁,这种特性来实现多线程的协调机制,同一时间只有一个线程对需要同步的代码块进行访问,具有原子性
可见性:必须确保在释放锁之前,对共享变量所做的修改,对于随后获得该锁的另外一个线程是可见的,即获得锁时是获取到最新的共享变量的值
SyncThread.java
public class SyncThread implements Runnable { @Override public void run() { String threadName = Thread.currentThread().getName(); if(threadName.startsWith("A")) async(); if(threadName.startsWith("B")) syncObjectBlack(); if(threadName.startsWith("C")) syncObjectMethod(); } //异步方法 private void async(){ try { System.out.println(Thread.currentThread().getName()+" async start at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" async end at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } //同步代码块synchronized(this/object){} private void syncObjectBlack(){ System.out.println(Thread.currentThread().getName()+" syncObjectBlack is gonna to start at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); synchronized (this){ try { System.out.println(Thread.currentThread().getName()+" syncObjectBlack start at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" syncObjectBlack end at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } //同步非静态方法synchronized method private synchronized void syncObjectMethod(){ System.out.println(Thread.currentThread().getName()+" syncObjectMethod is gonna to start at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); try { System.out.println(Thread.currentThread().getName()+" syncObjectMethod start at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" syncObjectMethod end at"+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } }
Test.java
public class Test { public static void main(String[] args){ SyncThread syncThread = new SyncThread(); Thread thread1 = new Thread(syncThread,"A_Thread_1"); Thread thread2 = new Thread(syncThread,"A_Thread_2"); Thread thread3 = new Thread(syncThread,"B_Thread_1"); Thread thread4 = new Thread(syncThread,"B_Thread_2"); Thread thread5 = new Thread(syncThread,"C_Thread_1"); Thread thread6 = new Thread(syncThread,"C_Thread_2"); thread1.start(); thread2.start(); thread3.start(); thread4.start(); thread5.start(); thread6.start(); } }
运行结果与解析
1:A类由于是执行异步方法,所以A2先开始后,A1可以没等A2结束也随之开始,甚至比A2提前结束,没有受到其他使用同步锁线程的影响
2:B2准备开始之后B1也准备开始,B1开始之后,B2需要等到B1到结束后,B2才可以开始,即B2需要等待syncThread这个对象的同步锁,由于start开始才是在synchronized里面,外面的准备开始的打印语句是异步执行的
3:C1准备开始后,因为这时候已经进入到方法中,C2必须等到C1结束后,才能准备开始到开始到结束,即一个线程在访问对象的同步方法时,另外一个需要等待其结束
4:下面C2运行的时候,B的两个线程与C1都需要等待C2完成,这是因为同步方法synchronized与同步块synchronized它们锁的是同一个对象
A_Thread_2 async start at 20:31:01 B_Thread_2 syncObjectBlack is gonna to start at 20:31:01 B_Thread_1 syncObjectBlack is gonna to start at 20:31:01 A_Thread_1 async start at 20:31:01 C_Thread_2 syncObjectMethod is gonna to start at 20:31:01 C_Thread_2 syncObjectMethod start at 20:31:01 A_Thread_1 async end at 20:31:02 A_Thread_2 async end at 20:31:02 C_Thread_2 syncObjectMethod end at 20:31:02 B_Thread_1 syncObjectBlack start at 20:31:02 B_Thread_1 syncObjectBlack end at 20:31:03 B_Thread_2 syncObjectBlack start at 20:31:03 B_Thread_2 syncObjectBlack end at 20:31:04 C_Thread_1 syncObjectMethod is gonna to start at 20:31:04 C_Thread_1 syncObjectMethod start at 20:31:04 C_Thread_1 syncObjectMethod end at 20:31:05
SyncThread.java
public class SyncThread implements Runnable { @Override public void run() { String threadName = Thread.currentThread().getName(); if(threadName.startsWith("A")) async(); if(threadName.startsWith("B")) syncObjectBlock(); if(threadName.startsWith("C")) syncObjectMethod(); if(threadName.startsWith("D")) syncClassBlock(); if(threadName.startsWith("E")) synClassMethod(); } //异步方法 private void async(){ try { System.out.println(Thread.currentThread().getName()+" async start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" async end at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } //同步代码块synchronized(this/object){} private void syncObjectBlock(){ System.out.println(Thread.currentThread().getName()+" syncObjectBlock is gonna to start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); synchronized (this){ try { System.out.println(Thread.currentThread().getName()+" syncObjectBlock start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" syncObjectBlock end at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } //同步非静态方法synchronized method private synchronized void syncObjectMethod(){ System.out.println(Thread.currentThread().getName()+" syncObjectMethod is gonna to start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); try { System.out.println(Thread.currentThread().getName()+" syncObjectMethod start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" syncObjectMethod end at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } private void syncClassBlock(){ System.out.println(Thread.currentThread().getName()+" syncClassBlock is gonna to start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); synchronized (SyncThread.class){ try { System.out.println(Thread.currentThread().getName()+" syncClassBlock start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" syncClassBlock end at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } private synchronized static void synClassMethod(){ System.out.println(Thread.currentThread().getName()+" synClassMethod is gonna to start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); try { System.out.println(Thread.currentThread().getName()+" synClassMethod start at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+" synClassMethod end at "+new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } }
1:Test.java:使用相同实例对象
public class Test { public static void main(String[] args){ SyncThread syncThread = new SyncThread(); Thread thread1 = new Thread(syncThread,"A_Thread_1"); Thread thread2 = new Thread(syncThread,"A_Thread_2"); Thread thread7 = new Thread(syncThread,"D_Thread_1"); Thread thread8 = new Thread(syncThread,"D_Thread_2"); Thread thread9 = new Thread(syncThread,"E_Thread_1"); Thread thread10 = new Thread(syncThread,"E_Thread_2"); thread1.start(); thread2.start(); thread7.start(); thread8.start(); thread9.start(); thread10.start(); } }
1:测试结果:使用相同实例对象
经过分析,结果跟获取对象锁相同对象的结果是一致的,运行流程一样
E_Thread_2 synClassMethod is gonna to start at 21:11:01 E_Thread_2 synClassMethod start at 21:11:01 D_Thread_1 syncClassBlock is gonna to start at 21:11:01 A_Thread_2 async start at 21:11:01 D_Thread_2 syncClassBlock is gonna to start at 21:11:01 A_Thread_1 async start at 21:11:01 A_Thread_2 async end at 21:11:02 A_Thread_1 async end at 21:11:02 E_Thread_2 synClassMethod end at 21:11:02 D_Thread_2 syncClassBlock start at 21:11:02 D_Thread_2 syncClassBlock end at 21:11:03 D_Thread_1 syncClassBlock start at 21:11:03 D_Thread_1 syncClassBlock end at 21:11:04 E_Thread_1 synClassMethod is gonna to start at 21:11:04 E_Thread_1 synClassMethod start at 21:11:04 E_Thread_1 synClassMethod end at 21:11:05
2:Test:使用不同实例对象
public class Test { public static void main(String[] args){ SyncThread syncThread = new SyncThread(); Thread thread1 = new Thread(new SyncThread(),"A_Thread_1"); Thread thread2 = new Thread(new SyncThread(),"A_Thread_2"); /*Thread thread3 = new Thread(syncThread,"B_Thread_1"); Thread thread4 = new Thread(syncThread,"B_Thread_2"); Thread thread5 = new Thread(syncThread,"C_Thread_1"); Thread thread6 = new Thread(syncThread,"C_Thread_2");*/ Thread thread7 = new Thread(new SyncThread(),"D_Thread_1"); Thread thread8 = new Thread(new SyncThread(),"D_Thread_2"); Thread thread9 = new Thread(new SyncThread(),"E_Thread_1"); Thread thread10 = new Thread(new SyncThread(),"E_Thread_2"); thread1.start(); thread2.start(); /*thread3.start(); thread4.start(); thread5.start(); thread6.start();*/ thread7.start(); thread8.start(); thread9.start(); thread10.start(); } }
2:测试结果:使用不同实例对象
1:A1与A2依旧是异步,不同类锁的影响
2:由于是类锁,即使是不同对象,结果跟获取对象锁相同对象的结果是一致的,运行流程一样
A_Thread_2 async start at 21:16:23 E_Thread_2 synClassMethod is gonna to start at 21:16:23 D_Thread_2 syncClassBlock is gonna to start at 21:16:23 D_Thread_1 syncClassBlock is gonna to start at 21:16:23 A_Thread_1 async start at 21:16:23 E_Thread_2 synClassMethod start at 21:16:23 E_Thread_2 synClassMethod end at 21:16:24 A_Thread_1 async end at 21:16:24 A_Thread_2 async end at 21:16:24 D_Thread_1 syncClassBlock start at 21:16:24 D_Thread_1 syncClassBlock end at 21:16:25 D_Thread_2 syncClassBlock start at 21:16:25 D_Thread_2 syncClassBlock end at 21:16:26 E_Thread_1 synClassMethod is gonna to start at 21:16:26 E_Thread_1 synClassMethod start at 21:16:26 E_Thread_1 synClassMethod end at 21:16:27
因为一个是类对象,一个是实例对象,所以是不同对象,两者互不干扰
Test.java
public class Test { public static void main(String[] args){ SyncThread syncThread = new SyncThread(); Thread thread1 = new Thread(new SyncThread(),"A_Thread_1"); Thread thread2 = new Thread(new SyncThread(),"A_Thread_2"); Thread thread3 = new Thread(syncThread,"B_Thread_1"); Thread thread4 = new Thread(syncThread,"B_Thread_2"); Thread thread5 = new Thread(syncThread,"C_Thread_1"); Thread thread6 = new Thread(syncThread,"C_Thread_2"); Thread thread7 = new Thread(new SyncThread(),"D_Thread_1"); Thread thread8 = new Thread(new SyncThread(),"D_Thread_2"); Thread thread9 = new Thread(new SyncThread(),"E_Thread_1"); Thread thread10 = new Thread(new SyncThread(),"E_Thread_2"); thread1.start(); thread2.start(); thread3.start(); thread4.start(); thread5.start(); thread6.start(); thread7.start(); thread8.start(); thread9.start(); thread10.start(); } }
测试结果:
从运行结果可以看到,第二行为对象锁的C1运行之后,还没结束,第十行为类锁的E2就可以开始,两者异步执行
C_Thread_1 syncObjectMethod is gonna to start at 21:22:22 C_Thread_1 syncObjectMethod start at 21:22:22 A_Thread_2 async start at 21:22:22 D_Thread_1 syncClassBlock is gonna to start at 21:22:22 A_Thread_1 async start at 21:22:22 D_Thread_2 syncClassBlock is gonna to start at 21:22:22 B_Thread_2 syncObjectBlock is gonna to start at 21:22:22 B_Thread_1 syncObjectBlock is gonna to start at 21:22:22 E_Thread_2 synClassMethod is gonna to start at 21:22:22 E_Thread_2 synClassMethod start at 21:22:22 A_Thread_2 async end at 21:22:23 C_Thread_1 syncObjectMethod end at 21:22:23 A_Thread_1 async end at 21:22:23 B_Thread_1 syncObjectBlock start at 21:22:23 E_Thread_2 synClassMethod end at 21:22:23 D_Thread_2 syncClassBlock start at 21:22:23 B_Thread_1 syncObjectBlock end at 21:22:24 B_Thread_2 syncObjectBlock start at 21:22:24 D_Thread_2 syncClassBlock end at 21:22:24 D_Thread_1 syncClassBlock start at 21:22:24 B_Thread_2 syncObjectBlock end at 21:22:25 C_Thread_2 syncObjectMethod is gonna to start at 21:22:25 C_Thread_2 syncObjectMethod start at 21:22:25 D_Thread_1 syncClassBlock end at 21:22:25 E_Thread_1 synClassMethod is gonna to start at 21:22:25 E_Thread_1 synClassMethod start at 21:22:25 C_Thread_2 syncObjectMethod end at 21:22:26 E_Thread_1 synClassMethod end at 21:22:26
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。