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