我在学习synchronized的时候,十分好奇当一个线程进入了一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

  然后就做了个实验(实验代码最后贴出),最后得到了如下结论。

现在分两种情况来讨论:1.当前线程调用的是synchronized普通方法(相对于static方法);2.当前线程调用的是synchronized static方法。

 1.当前线程调用的是synchronized普通方法(相对于static方法)时,其它线程是否可进入此对象的其它方法:

  1)其它方法是加了synchronized的普通方法,不能;

  2)其它方法是没加synchronized的普通方法,能;

  3)其它方法是synchronized的static方法,能;

  4)其它方法是没加synchronized的static方法,能。

 2.当前线程调用的是synchronized static方法,其它线程是否可进入此对象的其它方法:

  1)其它方法是加了synchronized的普通方法,能;

  2)其它方法是没加synchronized的普通方法,能;

  3)其它方法是synchronized的static方法,不能;

  4)其它方法中有synchronized(xxx.class)的,不能;

  5)其它方法是没加synchronized的static方法,能。

  其实只要明白了普通方法加synchronized的本质是给对象的this加了对象锁,上面的结论就不难理解了,

  其中不管static方法是否加synchroized,只要锁的是this,即当前对象,而不是当前类(XXX.class),就可以执行;

  而给当前类加锁时,除了同步的static方法不能调用外,其它的都可以。

  

  实验代码如下:

package javaBase;

public class JB_052_Synchronized {
public static void main(String[] args) {
Resource_052 rs = new Resource_052(); Thread t1 = new Thread(new Thread1_052(rs)); //调用synchronized方法的线程
Thread t0 = new Thread(new Thread0_052(rs)); //调用普通方法的线程
Thread t2 = new Thread(new Thread2_052(rs)); //调用另一个synchronized方法的线程
Thread t3 = new Thread(new Thread3_052(rs)); //调用synchronized static 方法的线程
Thread t4 = new Thread(new Thread4_052(rs)); //调用static方法的线程 Thread t5 = new Thread(new Thread5_052(rs)); //调用锁class方法的线程 t1.start(); //调用了synchronized方法
try{
System.out.println("调用synchronized方法的thread1启动后主程序等待2秒,确保在其它线程执行之前thread1获得对象锁");
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
t0.start(); //调用了普通方法 //可以
t2.start(); //调用了另一个synchronized方法 //不行
t3.start(); //调用了synchronized static 方法 //可以
t4.start(); //调用了static方法 //可以 //锁class
try{
System.out.println("主程序等待10秒,等前面的线程除thread1和被阻塞的线程外都执行完成,后面的代码将做锁class测试....");
Thread.sleep(10000);
System.out.println("10秒等待完。");
}catch(InterruptedException e){
e.printStackTrace();
}
//thread5中会置flag=false终止thread1
t5.start();
try{
System.out.println("主程序等待10秒,确保thread5获得class的对象锁,确保thread1和被阻塞的线程都终止。");
Thread.sleep(10000);
System.out.println("10秒等待完。");
}catch(InterruptedException e){
e.printStackTrace();
} t0 = new Thread(new Thread0_052(rs)); //普通方法
t2 = new Thread(new Thread2_052(rs)); //另一个synchronized方法
t3 = new Thread(new Thread3_052(rs)); //synchronized static 方法
t4 = new Thread(new Thread4_052(rs)); //static方法 t0.start(); //调用了普通方法 //可以
t2.start(); //调用了另一个synchronized方法 //不行
t3.start(); //调用了synchronized static 方法 //不可以
t4.start(); //调用了static方法 //可以
}
} class Resource_052{
public boolean flag = true; public void method0(){
System.out.println("this is a ordinary method——method0.");
}
synchronized public void method1(){
while(flag){
System.out.println("this is a synchronized method——method1.");
try{
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
synchronized public void method2(){
System.out.println("this is the second synchronized method——method2.");
}
synchronized public static void method3(){
System.out.println("this is a synchronized static method——method3.");
}
public static void method4(){
System.out.println("this is a ordinary static method——method4.");
} public void method5(){
synchronized(Resource_052.class){
while(true){
System.out.println("this is a synchronized static method——method5.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} synchronized public static void method6(){ //与method5等价
while(true){
System.out.println("this is a synchronized static method——method6.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} } class Thread1_052 implements Runnable{
private Resource_052 rs;
/**
* constructor
* @param rs
*/
public Thread1_052(Resource_052 rs){
this.rs = rs;
}
@Override
public void run(){
this.rs.method1(); //调用synchronized方法
}
}
class Thread0_052 implements Runnable{
private Resource_052 rs;
/**
* constructor
* @param rs
*/
public Thread0_052(Resource_052 rs){
this.rs = rs;
}
@Override
public void run(){
this.rs.method0(); //调用普通方法
}
}
class Thread2_052 implements Runnable{
private Resource_052 rs;
/**
* constructor
* @param rs
*/
public Thread2_052(Resource_052 rs){
this.rs = rs;
}
@Override
public void run(){
this.rs.method2(); //调用另一个synchronized方法
}
}
class Thread3_052 implements Runnable{
private Resource_052 rs;
/**
* constructor
* @param rs
*/
public Thread3_052(Resource_052 rs){
this.rs = rs;
}
@Override
public void run(){
this.rs.method3(); //调用synchronized static方法
}
}
class Thread4_052 implements Runnable{
private Resource_052 rs;
/**
* constructor
* @param rs
*/
public Thread4_052(Resource_052 rs){
this.rs = rs;
}
@Override
public void run(){
this.rs.method4(); //调用普通static方法
}
}
class Thread5_052 implements Runnable{
private Resource_052 rs;
/**
* constructor
* @param rs
*/
public Thread5_052(Resource_052 rs){
this.rs = rs;
}
@Override
public void run(){
rs.flag=false;
this.rs.method5(); //调用锁Class的方法
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

  得到的结果如下:

==================================================================================================

调用synchronized方法的thread1启动后主程序等待2秒,确保在其它线程执行之前thread1获得对象锁
this is a synchronized method——method1.
this is a synchronized method——method1.
主程序等待10秒,等前面的线程除thread1和被阻塞的线程外都执行完成,后面的代码将做锁class测试....
this is a ordinary method——method0.
this is a synchronized static method——method3.
this is a ordinary static method——method4.      //从这里的结果可以看到synchronized 普通方法method3没有执行
this is a synchronized method——method1.
this is a synchronized method——method1.
this is a synchronized method——method1.
this is a synchronized method——method1.
10秒等待完。
主程序等待10秒,确保thread5获得class的对象锁,确保thread1和被阻塞的线程都终止。
this is a synchronized static method——method5.
this is the second synchronized method——method2.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
10秒等待完。
this is a ordinary method——method0.
this is a ordinary static method——method4.
this is the second synchronized method——method2.  //可以看到synchronized static方法method3没有执行
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.
this is a synchronized static method——method5.

==================================================================================================

最新文章

  1. 伪随机数(线性同余法)C语言
  2. OJ-Triangle
  3. js图形网站
  4. 【前端也要学点算法】 归并排序的JavaScript实现
  5. Simplest way to serve static data from outside the application server in a Java web application
  6. word 与 endnote 反应慢的小技巧
  7. 在mac上安装hadoop伪分布式
  8. zendstudio的安装与配置
  9. oralce
  10. 05 python 初学(列表)
  11. bzoj3412
  12. This Jenkins instance appears to be offline
  13. 9. 一个list拆分成多个list返回
  14. Populating Next Right Pointers in Each Node II leetcode java
  15. 洛谷P3806 点分治1 & POJ1741 Tree & CF161D Distance in Tree
  16. 计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll解决办法
  17. OSGi 系列(十二)之 Http Service
  18. HDFS系列 -- HDFS预研
  19. TogetherJS本地部署,基于websocket的网页即时视频、语音、文字聊天
  20. Android UI【android 仿微信、QQ聊天,带表情,可翻页,带翻页拖动缓冲】

热门文章

  1. php实验一
  2. 配置tomcat的虚拟路径
  3. Mathematics:Pseudoprime numbers(POJ 3641)
  4. [Android进阶]学习AccessibilityService实现微信抢红包插件
  5. 在cmd窗口中运行php命令
  6. centOS目录结构
  7. linux安装软件
  8. Java观察者模式(Observer模式)
  9. Django搭建简易博客
  10. Android 反编译 -- apktool、dex2jar、jd-gui