对于synchronized的理解

 

一、synchronized

  同步关键字,分为同步代码块和同步函数

二、对synchronized的理解(未加static关键字)(以下所说:对同步方法和同步代码块均适用)

  对象的创建是以类为模板的

  1、两个并发的线程访问同一个类Object中的synchronized(this)同步代码块或者同步方法时,同一时间只能执行一个,另一个必须要等待当前线程执行完才能执行(同一个对象:见下面的testSynchronized,分为两个线程,两个线程访问的是一个方法)(一个对象两个线程一个方法)

     例子:

 1 public class TestSynchronized {
 2     public void test1(){
 3         synchronized(this) {
 4             System.out.println("1"+this);
 5             int i = 5; 
 6              while( i-- > 0) {
 7                  System.out.println(Thread.currentThread().getName() + " : " + i);  
 8                  try {
 9                     Thread.sleep(500);
10                 } catch (InterruptedException e) {
11                     // TODO Auto-generated catch block
12                     e.printStackTrace();
13                 }
14              }
15         }
16     }
17     public static void main(String[] args) {
18         final TestSynchronized testSynchronized = new TestSynchronized();
19         final TestSynchronized testSynchronized1 = new TestSynchronized();
20         Thread thread1 = new Thread(new Runnable() {
21             
22             @Override
23             public void run() {
24                 testSynchronized.test1();
25             }
26         },"test1");
27         Thread thread3 = new Thread(new Runnable() {
28             
29             @Override
30             public void run() {
31                 testSynchronized.test1();
32             }
33         },"test3");
34         
35         thread1.start();
36         thread3.start();
37     }
38 }

结果:

  2、两个并发的线程访问同一个类Object中的synchronized(this)同步代码块或者同步方法时,两个交替进行,因为对象的创建是以类为模板的,所以两个对象都会有自己独立的方法(不同对象:testSynchronized和testSynchronized1,分为两个线程,两个线程访问的是一个方法)(两个对象两个线程一个方法)

   例子:和第一个的例子相比仅仅修改了第31行

 1 public class TestSynchronized {
 2     public void test1(){
 3         synchronized(this) {
 4             System.out.println("1"+this);
 5             int i = 5; 
 6              while( i-- > 0) {
 7                  System.out.println(Thread.currentThread().getName() + " : " + i);  
 8                  try {
 9                     Thread.sleep(500);
10                 } catch (InterruptedException e) {
11                     // TODO Auto-generated catch block
12                     e.printStackTrace();
13                 }
14              }
15         }
16     }
17     public static void main(String[] args) {
18         final TestSynchronized testSynchronized = new TestSynchronized();
19         final TestSynchronized testSynchronized1 = new TestSynchronized();
20         Thread thread1 = new Thread(new Runnable() {
21             
22             @Override
23             public void run() {
24                 testSynchronized.test1();
25             }
26         },"test1");
27         Thread thread3 = new Thread(new Runnable() {
28             
29             @Override
30             public void run() {
31                 testSynchronized1.test1();
32             }
33         },"test3");
34         thread1.start();
35         thread3.start();
36     }
37 }

  结果:

  

  3、(两个线程同一对象)当一个线程已经访问了该类中的一个synchronized方法,另一个线程就不能再去访问访问其他的synchronized方法(对象锁是锁住了对象,所以只能执行完这个再去执行另一个)(一个对象两个线程两个方法)

  例子:

 1 public class TestSynchronized {
 2     public void test1(){
 3         synchronized(this) {
 4             System.out.println("1"+this);
 5             int i = 5; 
 6              while( i-- > 0) {
 7                  System.out.println(Thread.currentThread().getName() + " : " + i);  
 8                  try {
 9                     Thread.sleep(500);
10                 } catch (InterruptedException e) {
11                     // TODO Auto-generated catch block
12                     e.printStackTrace();
13                 }
14              }
15         }
16     }
17     public synchronized void test2(){
18         System.out.println(this);
19         int i = 5; 
20          while( i-- > 0) {
21              System.out.println(Thread.currentThread().getName() + " : " + i);  
22              try {
23                 Thread.sleep(500);
24             } catch (InterruptedException e) {
25                 e.printStackTrace();
26             }
27          }
28     }
29     public static void main(String[] args) {
30         final TestSynchronized testSynchronized = new TestSynchronized();
31         final TestSynchronized testSynchronized1 = new TestSynchronized();
32         Thread thread1 = new Thread(new Runnable() {
33             
34             @Override
35             public void run() {
36                 testSynchronized.test1();
37             }
38         },"test1");
39         Thread thread2 = new Thread(new Runnable() {
40             
41             @Override
42             public void run() {
43                 testSynchronized.test2();
44             }
45         },"test2");
46         thread1.start();
47         thread2.start();
48     }
49 }

  结果:

  

  4、(同一个对象)当一个线程已经访问了一个类的synchronized方法,那么另一个线程也可以访问其他的非synchronized方法,结果是交替进行的(一个对象两个线程两个方法[一个synchronized一个非synchronized的])

    进行了同步的方法(加锁方法)和没有进行同步的方法(普通方法)是互不影响的,一个线程进入了同步方法,得到了对象锁,其他线程还是可以访问那些没有同步的方法(普通方法)

    例子:

 1 public class TestSynchronized {
 2     public void test1(){
 3         synchronized(this) {
 4             System.out.println("1"+this);
 5             int i = 5; 
 6              while( i-- > 0) {
 7                  System.out.println(Thread.currentThread().getName() + " : " + i);  
 8                  try {
 9                     Thread.sleep(500);
10                 } catch (InterruptedException e) {
11                     // TODO Auto-generated catch block
12                     e.printStackTrace();
13                 }
14              }
15         }
16     }
17         //非synchronized
18     public void test2(){
19         System.out.println(this);
20         int i = 5; 
21          while( i-- > 0) {
22              System.out.println(Thread.currentThread().getName() + " : " + i);  
23              try {
24                 Thread.sleep(500);
25             } catch (InterruptedException e) {
26                 e.printStackTrace();
27             }
28          }
29     }
30     public static void main(String[] args) {
31         final TestSynchronized testSynchronized = new TestSynchronized();
32         final TestSynchronized testSynchronized1 = new TestSynchronized();
33         Thread thread1 = new Thread(new Runnable() {
34             
35             @Override
36             public void run() {
37                 testSynchronized.test1();
38             }
39         },"test1");
40         Thread thread2 = new Thread(new Runnable() {
41             
42             @Override
43             public void run() {
44                 testSynchronized.test2();
45             }
46         },"test2");
47         
48         thread2.start();
49         thread1.start();
50     }
51 }

  结果:

  

三、加了static后现成的执行

  1、对于一个类,一个线程访问了加了static的synchronized方法,另一个线程同样可以访问未加static的synchronized方法,所以结果是交替进行,因为类和对象不同(static修饰后锁住的是类,所有对象共享,而没有加static锁住的是对象,只有每个对象私有)(一个对象一个类两个线程两个方法

  例子:

 1 public class TestSynchronized {
 2     public void test1(){
 3         synchronized(this) {
 4             int i = 5; 
 5              while( i-- > 0) {
 6                  System.out.println(Thread.currentThread().getName() + " : " + i);  
 7                  try {
 8                     Thread.sleep(500);
 9                 } catch (InterruptedException e) {
10                     // TODO Auto-generated catch block
11                     e.printStackTrace();
12                 }
13              }
14         }
15     }
16     public static synchronized void test2(){
17         int i = 5; 
18          while( i-- > 0) {
19              System.out.println(Thread.currentThread().getName() + " : " + i);  
20              try {
21                 Thread.sleep(500);
22             } catch (InterruptedException e) {
23                 e.printStackTrace();
24             }
25          }
26     }
27     public static void main(String[] args) {
28         final TestSynchronized testSynchronized = new TestSynchronized();
29         Thread thread1 = new Thread(new Runnable() {
30             
31             @Override
32             public void run() {
            //对象调用的是该对象自己的方法
33 testSynchronized.test1(); 34 } 35 },"test1"); 36 Thread thread2 = new Thread(new Runnable() { 37 38 @Override 39 public void run() {
           //类调用的是类方法
40 TestSynchronized.test2(); 41 } 42 },"test2"); 43 thread2.start(); 44 thread1.start(); 45 } 46 }

  结果:

  

  2、两个都是被static修饰的synchronized方法,结果是一个线程等待另一个线程执行完才会执行,因为类是一样的(和同一个对象的理解差不多),方法被synchronized修饰只能一个执行完再执行另一个(一个类两个线程两个方法)

  例子:

 1 public class TestSynchronized {
 2     public static void test1(){
 3         synchronized(TestSynchronized.class) {
 4             int i = 5; 
 5              while( i-- > 0) {
 6                  System.out.println(Thread.currentThread().getName() + " : " + i);  
 7                  try {
 8                     Thread.sleep(500);
 9                 } catch (InterruptedException e) {
10                     // TODO Auto-generated catch block
11                     e.printStackTrace();
12                 }
13              }
14         }
15     }
16     public static synchronized void test2(){
17         int i = 5; 
18          while( i-- > 0) {
19              System.out.println(Thread.currentThread().getName() + " : " + i);  
20              try {
21                 Thread.sleep(500);
22             } catch (InterruptedException e) {
23                 e.printStackTrace();
24             }
25          }
26     }
27     public static void main(String[] args) {
28         final TestSynchronized testSynchronized = new TestSynchronized();
29         Thread thread1 = new Thread(new Runnable() {
30             
31             @Override
32             public void run() {
33                 TestSynchronized.test1();
34             }
35         },"test1");
36         Thread thread2 = new Thread(new Runnable() {
37             
38             @Override
39             public void run() {
40                 TestSynchronized.test2();
41             }
42         },"test2");
43         
44         thread2.start();
45         thread1.start();
46     }
47 }

  结果:

  

 

 

补充:

  面试的一道题:

    一个只被synchronized修饰的方法fun(),现有两个对象a,b,分别是两个线程t1,t2

    ①a.fun()和b.fun()可以同时进行吗?

      答:可以,因为是两个为不同的对象,对象的创建是以类为模板的,所以这两个对象中都会有自己的fun()方法,所以两个线程开启后会交替进行,如上面的二2

    ②回答完可以后,怎么可以让两个分开进行即一个完了之后再进行另一个?

      答:给方法加上static关键字,static锁住了类,此时锁为“类锁”,所以虽然对象不一样但是类都是一样的,所以简单说就是一个类两个线程调用一个方法,肯定是一个执行完再执行另一个

  

  

    

 

  

    

转载于:https://www.cnblogs.com/rgever/p/9756939.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值