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行将是正常的打印各自的名字
来源:https://www.cnblogs.com/yangzhilong/p/4752480.html