从头认识多线程-2.24 修改监视器对同步的影响

Posted 李灵晖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从头认识多线程-2.24 修改监视器对同步的影响相关的知识,希望对你有一定的参考价值。

这一章节我们来讨论一下修改监视器对同步的影响。

1.不修改监视器,同步的

package com.ray.deepintothread.ch02.topic_24;

/**
 * 
 * @author RayLee
 *
 */
public class SynchOfStaticInnerClass {

	public static void main(String[] args) {
		Thread thread = new Thread(new Runnable() {
			public void run() {
				MyService.updateA();
			}
		});
		thread.start();
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				MyService.updateB();
			}
		});
		thread2.start();
	}
}

class MyService {

	private static int id = 0;

	private static String lock = "a";

	public static void updateA() {
		synchronized (lock) {
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " id:" + id++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void updateB() {
		synchronized (lock) {
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " id:" + id++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

输出:

Thread name:Thread-0 id:0
Thread name:Thread-0 id:1
Thread name:Thread-0 id:2
Thread name:Thread-0 id:3
Thread name:Thread-0 id:4
Thread name:Thread-0 id:5
Thread name:Thread-0 id:6
Thread name:Thread-0 id:7
Thread name:Thread-0 id:8
Thread name:Thread-0 id:9
Thread name:Thread-1 id:10
Thread name:Thread-1 id:11
Thread name:Thread-1 id:12
Thread name:Thread-1 id:13
Thread name:Thread-1 id:14
Thread name:Thread-1 id:15
Thread name:Thread-1 id:16
Thread name:Thread-1 id:17
Thread name:Thread-1 id:18
Thread name:Thread-1 id:19


2.当修改发生在线程开始的时候,把同步变成异步

package com.ray.deepintothread.ch02.topic_24;

/**
 * 
 * @author RayLee
 *
 */
public class SynchOfStaticInnerClass2 {

	public static void main(String[] args) {
		Thread thread = new Thread(new Runnable() {
			public void run() {
				MyService2.updateA();
			}
		});
		thread.start();
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				MyService2.updateB();
			}
		});
		thread2.start();
	}
}

class MyService2 {

	private static int a = 0;

	private static Object lock = new Object();

	public static void updateA() {
		synchronized (lock) {
			lock = new Object();
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void updateB() {
		synchronized (lock) {
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

输出:

Thread name:Thread-1 a:0
Thread name:Thread-0 a:0
Thread name:Thread-1 a:1
Thread name:Thread-0 a:2
Thread name:Thread-0 a:3
Thread name:Thread-1 a:4
Thread name:Thread-0 a:5
Thread name:Thread-1 a:6
Thread name:Thread-0 a:7
Thread name:Thread-1 a:8
Thread name:Thread-1 a:9
Thread name:Thread-0 a:10
Thread name:Thread-0 a:11
Thread name:Thread-1 a:12
Thread name:Thread-1 a:13
Thread name:Thread-0 a:14
Thread name:Thread-0 a:15
Thread name:Thread-1 a:16
Thread name:Thread-0 a:17
Thread name:Thread-1 a:18


这里原因不明,笔者曾尝试过在for里面每执行一次就输出相应的lock,都是一样的,但是,从输出结果就已经可以看见,其实已经是不同步的了


3.当修改发生在线程开始了一段时间之后,对同步没有影响

package com.ray.deepintothread.ch02.topic_24;

/**
 * 
 * @author RayLee
 *
 */
public class SynchOfStaticInnerClass3 {

	public static void main(String[] args) {
		Thread thread = new Thread(new Runnable() {
			public void run() {
				MyService3.updateA();
			}
		});
		thread.start();
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				MyService3.updateB();
			}
		});
		thread2.start();
	}
}

class MyService3 {

	private static int a = 0;

	private static Object lock = new Object();

	public static void updateA() {
		synchronized (lock) {
			for (int i = 0; i < 10; i++) {
				if (i == 5) {//把对监视器的修改延时了
					lock = new Object();
				}
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void updateB() {
		synchronized (lock) {
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

输出:

Thread name:Thread-0 a:0
Thread name:Thread-0 a:1
Thread name:Thread-0 a:2
Thread name:Thread-0 a:3
Thread name:Thread-0 a:4
Thread name:Thread-0 a:5
Thread name:Thread-0 a:6
Thread name:Thread-0 a:7
Thread name:Thread-0 a:8
Thread name:Thread-0 a:9
Thread name:Thread-1 a:10
Thread name:Thread-1 a:11
Thread name:Thread-1 a:12
Thread name:Thread-1 a:13
Thread name:Thread-1 a:14
Thread name:Thread-1 a:15
Thread name:Thread-1 a:16
Thread name:Thread-1 a:17
Thread name:Thread-1 a:18
Thread name:Thread-1 a:19


package com.ray.deepintothread.ch02.topic_24;

/**
 * 
 * @author RayLee
 *
 */
public class SynchOfStaticInnerClass4 {

	public static void main(String[] args) {
		Thread thread = new Thread(new Runnable() {
			public void run() {
				try {
					MyService4.updateA();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		thread.start();
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				MyService4.updateB();
			}
		});
		thread2.start();
	}
}

class MyService4 {

	private static int a = 0;

	private static Object lock = new Object();

	public static void updateA() throws InterruptedException {
		synchronized (lock) {
			Thread.sleep(300);//把对监视器的修改延时了
			lock = new Object();
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void updateB() {
		synchronized (lock) {
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

输出:

Thread name:Thread-0 a:0
Thread name:Thread-0 a:1
Thread name:Thread-0 a:2
Thread name:Thread-0 a:3
Thread name:Thread-0 a:4
Thread name:Thread-0 a:5
Thread name:Thread-0 a:6
Thread name:Thread-0 a:7
Thread name:Thread-0 a:8
Thread name:Thread-0 a:9
Thread name:Thread-1 a:10
Thread name:Thread-1 a:11
Thread name:Thread-1 a:12
Thread name:Thread-1 a:13
Thread name:Thread-1 a:14
Thread name:Thread-1 a:15
Thread name:Thread-1 a:16
Thread name:Thread-1 a:17
Thread name:Thread-1 a:18
Thread name:Thread-1 a:19


4.修改监视器对象的属性,对同步没有影响

package com.ray.deepintothread.ch02.topic_24;

/**
 * 
 * @author RayLee
 *
 */
public class SynchOfStaticInnerClass5 {

	public static void main(String[] args) {
		MyService5 myService5 = new MyService5();
		Thread thread = new Thread(new Runnable() {
			public void run() {
				try {
					myService5.updateA();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		thread.start();
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				myService5.updateB();
			}
		});
		thread2.start();
	}
}

class MyService5 {

	private static int a = 0;

	private static Monitor lock;

	public MyService5() {
		lock = new Monitor();
		lock.id = 1;
	}

	public void updateA() throws InterruptedException {
		synchronized (lock) {
			lock.id = 2;// 修改对象的属性
			Thread.sleep(300);
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void updateB() {
		synchronized (lock) {
			for (int i = 0; i < 10; i++) {
				System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

class Monitor {
	public int id = 0;
}


输出:

Thread name:Thread-0 a:0
Thread name:Thread-0 a:1
Thread name:Thread-0 a:2
Thread name:Thread-0 a:3
Thread name:Thread-0 a:4
Thread name:Thread-0 a:5
Thread name:Thread-0 a:6
Thread name:Thread-0 a:7
Thread name:Thread-0 a:8
Thread name:Thread-0 a:9
Thread name:Thread-1 a:10
Thread name:Thread-1 a:11
Thread name:Thread-1 a:12
Thread name:Thread-1 a:13
Thread name:Thread-1 a:14
Thread name:Thread-1 a:15
Thread name:Thread-1 a:16
Thread name:Thread-1 a:17
Thread name:Thread-1 a:18
Thread name:Thread-1 a:19


总结:这一章节我们总结了几种修改监视器对同步的影响。


这一章节就到这里,谢谢

------------------------------------------------------------------------------------

我的github:https://github.com/raylee2015/DeepIntoThread


目录:http://blog.csdn.net/raylee2007/article/details/51204573


以上是关于从头认识多线程-2.24 修改监视器对同步的影响的主要内容,如果未能解决你的问题,请参考以下文章

重新认识synchronized(下)

多线程(02)

从头认识多线程-1.9 迫使线程停止的方法-return法

从头认识java-17.4 具体解释同步-具体解释竞争条件

从头认识多线程-1.8 迫使线程停止的方法-暴力Stop方法

从头认识多线程-1.16 对照不同的优先级