2、传统的线程互斥synchronized

こ雲淡風輕ζ 提交于 2020-02-29 14:35:21

synchronized使用之基本原则:

synchronized可以锁方法,也可以锁代码片段,但要实现互斥的基本就是在想要互斥的代码上加”同一把锁“,也就是同一个对象,也就是用==判断等于true的对象

下面看一个例子:

Work.java    真正做事情的类

 1 package com.yzl;
 2 
 3 public class Work {
 4     /**
 5      * 未同步的
 6      * @param name
 7      */
 8     public void noSynwrite(String name){
 9         for(int i=0; i<name.length(); i++){
10             System.out.print(name.charAt(i));
11             if(i == (name.length()-1)){
12                 System.out.print("\n");
13             }
14         }
15     }
16     
17     /**
18      * 使用同步块,并使用Work的实例对象做为锁
19      * 此方法的同步需保证是调用该方法的work对象是同一个
20      * @param name
21      */
22     public void write1(String name){
23         synchronized (this) {
24             for(int i=0; i<name.length(); i++){
25                 System.out.print(name.charAt(i));
26                 if(i == (name.length()-1)){
27                     System.out.print("\n");
28                 }
29             }
30         }
31     }
32     
33     /**
34      * 使用同步块,并使用Work的字节码做为锁
35      * @param name
36      */
37     public void write1WithStatic(String name){
38         synchronized (Work.class) {
39             for(int i=0; i<name.length(); i++){
40                 System.out.print(name.charAt(i));
41                 if(i == (name.length()-1)){
42                     System.out.print("\n");
43                 }
44             }
45         }
46     }
47     
48     /**
49      * 使用同步的方法,锁对象为ork的实例对象
50      * 此方法的同步需保证是调用该方法的work对象是同一个
51      * @param name
52      */
53     public synchronized void write2(String name){
54         for(int i=0; i<name.length(); i++){
55             System.out.print(name.charAt(i));
56             if(i == (name.length()-1)){
57                 System.out.print("\n");
58             }
59         }
60     }
61     
62     /**
63      * 静态方法的同步方法,同步的对象是对象的字节码,也就是Work.class
64      * 如果要与上面的方法一起使用并保持互斥,则可以把write1的锁对象this改成Work.class
65      * @param name
66      */
67     public synchronized static void write3(String name){
68         for(int i=0; i<name.length(); i++){
69             System.out.print(name.charAt(i));
70             if(i == (name.length()-1)){
71                 System.out.print("\n");
72             }
73         }
74     }
75 }

 

测试类ThreadPart_2.java

 1 package com.yzl;
 2 
 3 /**
 4  * 传统的线程互斥
 5  * 原理:使用同一个对象(锁)才能实现,
 6  *         静态方法的同步则只能使用类的字节码也就是ClassName.class来做锁
 7  * @author yzl
 8  *
 9  */
10 public class ThreadPart_2 {
11     public static void main(String[] args) {
12         noSyn();
13         synWithOneObj();
14         synWithOneStaticObj();
15     }
16     
17     /**
18      * 未线程同步的
19      */
20     private static void noSyn(){
21         final Work work = new Work();
22         
23         Thread thread = new Thread(new Runnable() {
24             @Override
25             public void run() {
26                 while(true){
27                     work.noSynwrite("wangwu");
28                 }
29             }
30         });
31         thread.start();
32         
33         Thread thread1 = new Thread(new Runnable() {
34             @Override
35             public void run() {
36                 while(true){
37                     work.noSynwrite("zhangsan");
38                 }
39             }
40         });
41         thread1.start();
42     }
43     
44     /**
45      * 使用同一个实例对象做为锁的
46      */
47     private static void synWithOneObj(){
48         final Work work = new Work();
49         
50         Thread thread = new Thread(new Runnable() {
51             @Override
52             public void run() {
53                 while(true){
54                     work.write1("wangwu");
55                 }
56             }
57         });
58         thread.start();
59         
60         Thread thread1 = new Thread(new Runnable() {
61             @Override
62             public void run() {
63                 while(true){
64                     work.write2("zhangsan");
65                 }
66             }
67         });
68         thread1.start();
69     }
70     
71     /**
72      * 使用同一个类的字节码做为锁的
73      */
74     private static void synWithOneStaticObj(){
75         Thread thread = new Thread(new Runnable() {
76             @Override
77             public void run() {
78                 while(true){
79                     new Work().noSynwrite("wangwu");
80                 }
81             }
82         });
83         thread.start();
84         
85         Thread thread1 = new Thread(new Runnable() {
86             @Override
87             public void run() {
88                 while(true){
89                     Work.write3("zhangsan");
90                 }
91             }
92         });
93         thread1.start();
94     }
95 }

将上面ThreadPart_2的第12、13、14行代码分别依次执行,

第12行代码将出现如下类似结果:

//运行结果部分示例
zhangsan
zhwu
wangwu
wangangsan
zhangsawangwu

第13和14行将是正常的打印各自的名字

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!