Java中同一个类中的不同synchronized方法不能并发执行。当多个线程访问同一个类的synchronized方法时,都是串行执行的!即使有多个CPU!synchronized方法使用了Java内置类Lock,即方法锁定的对象。同一个锁一次只能被一个执行线程获取,所以其他线程只能等待锁被释放。所以,即使你有额外的cpu可以执行,但是你没有加锁,所以还是不能进入synchronized方法执行,CPU因此空闲。如果一个线程长期持有竞争性很强的锁,会导致其他线程因等待释放而挂起,导致CPU得不到Utilization,系统吞吐量低。因此,尽量避免某个线程长期持有锁!验证码publicclassSyncMethod{publicsynchronizedvoidsyncMethod2(){try{System.out.println("@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,已经获取内置锁`SyncMethod.this`)");线程.睡眠(5000);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,即将释放内置锁`SyncMethod.this`)");}publicsynchronizedvoidsyncMethod1(){System.out.println("#########################(syncMethod1,已获取内置锁`SyncMethod.this`,并将退出)");}staticclassThread1extendsThread{SyncMethods异步方法;publicThread1(SyncMethodsyncMethod){this.syncMethod=syncMethod;}@Overridepublicvoidrun(){syncMethod.syncMethod2();}}staticclassThread2extendsThread{SyncMethodsyncMethod;publicThreadMethods2(SyncMethods){syncMethod=syncMethod;}@Overridepublicvoidrun(){System.out.println("Thread2running...");syncMethod.syncMethod1();}}publicstaticvoidmain(String[]args)throwsInterruptedException{SyncMethodsyncMethod=newSyncMethod();Thread1thread1=newThread1(syncMethod);Thread2thread2=newThread2(syncMethod);thread1.start();//先执行抢占锁Thread.sleep(500);//放弃cpu,让thread1执行以获得锁thread2.start();//syncMethod1()方法获取到锁后,检查syncMethod2()方法是否可以执行/*同一个对象的不同synchrs是否可以并发执行onized方法,即看是否可以同时进入一个对象synchronized方法块1.创建一个对象`syncMethod`,有两个synchronized方法2.先启动一个线程(Thread1),让它进入synchronized方法(syncMethod对象的(syncMethod1)),并在synchronized方法中停止3.启动另一个线程(Thread2),执行syncMethod对象的一个??synchronized方法(syncMethod2),看是否可以进入这个方法并输出如下:@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,alreadyacquiredbuilt-inlock`SyncMethod.this`)Thread2running...@@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,即将释放内置锁`SyncMethod.this`)#########################(syncMethod1,已获取内置锁`SyncMethod.this`,即将退出)结果分析:观察发现会在之后停顿几秒输出`Thread2running...`(Thread2无法获得锁并被挂起,因为锁已经被Thread1持有)。如果不同线程可以同时访问同一个对象的不同synchronized方法,当有足够的cpu时间片时(Thread1在调用syncMethod1时使用Thread.sleep让出cpu),应该立即执行Thread2调用的syncMethod2方法,即syncMethod2方法中的语句是在输出`Thread2running...`语句后立即输出,而不是等待几秒后输出(应该是因为没有其他线程与Thread2竞争此时的cpu,而且当前电脑不是只有一个cpu),所以得出结论Conclusion:"不同线程不能同时执行一个对象的不同synchrosnizedmethod"其实这个结论很明显,原理前面已经讲清楚了,这里不再赘述。*/}}下面是一些锁的使用建议:①为了避免锁的竞争,可以使用锁分解,锁分段,减少线程持有锁的时间②如果申诉程序中的syncMethod1和syncMethod2方法是两个不相关的方法(请求的资源之间没有关系),那么这两个方法可以使用两种不同的锁分别改造后Thread1和Thread2不会因为锁竞争而挂掉,修改后的SyncMethod类如下:锁定两个不同的Object对象(lock1,lock2)publicclassSyncMethod{privateObjectlock1=newObject();privateObjectlock2=newObject();publicvoidsyncMethod2(){synchronized(lock1){try{System.out.println("@@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,已获取内置锁`SyncMethod.this`)");Thread.sleep(5000);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,即将释放内置锁`SyncMethod.this`)");}}publicvoidsyncMethod1(){synchronized(lock2){System.out.println("##########################(ssyncMethod1,已经获取了内置锁`SyncMethod.this`,即将退出)");}}}当然,如果syncMethod1中的耗时操作与锁定的资源无关,那么时间耗操作也可以移出同步块,在上述改造中syncMethod1在以下基础上进一步修改如下:publicvoidsyncMethod2(){synchronized(lock1){System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,已经获取了内置锁`SyncMethod.this`)");System.out.println("@@@@@@@@@@@@@@@@@@@@@@(syncMethod2,abouttoreleasethebuilt-inlock`SyncMethod.this`)");}//将耗时操作移出同步块try{Thread.sleep(5000);//无事可做的耗时操作处理同步使用的资源}catch(InterruptedExceptione){e.printStackTrace();}}
