从头认识多线程-2.7 同步方法的隐患

这一章节我们来讨论一下同步方法的隐患。

1.同步虽然给我们带来数据的一致性,但是,同时也降低了性能,代码清单:

package com.ray.deepintothread.ch02.topic_8;

import java.sql.Time;

/**
 * <br>
 * <br>
 *
 * @author RayLee
 *
 */
public class ThreatOfSynch {
	public static void main(String[] args) throws InterruptedException {
		MyService myService = new MyService();
		ThreadOne threadOne = new ThreadOne(myService);
		Thread thread = new Thread(threadOne);
		thread.start();
		ThreadTwo threadTwo = new ThreadTwo(myService);
		Thread thread2 = new Thread(threadTwo);
		thread2.start();

		Thread.sleep(10000);
		System.out.println("application use time:" + (MyTimeUtil.END_TIME - MyTimeUtil.START_TIME));
	}
}

class ThreadOne implements Runnable {

	private MyService myService;

	public ThreadOne(MyService myService) {
		this.myService = myService;
	}

	@Override
	public void run() {
		myService.service();
	}
}

class ThreadTwo implements Runnable {

	private MyService myService;

	public ThreadTwo(MyService myService) {
		this.myService = myService;
	}

	@Override
	public void run() {
		myService.service();
	}
}

class MyService {

	private void queryDataFromServer() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private void updateDataFromServer() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private void retrunDataFromServer() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public synchronized void service() {
		long startTime = System.currentTimeMillis();
		if (MyTimeUtil.START_TIME == 0) {
			MyTimeUtil.START_TIME = startTime;
		}
		queryDataFromServer();
		updateDataFromServer();
		retrunDataFromServer();
		long endTime = System.currentTimeMillis();
		if (endTime > MyTimeUtil.END_TIME) {
			MyTimeUtil.END_TIME = endTime;
		}
		System.out.println("Thread name:" + Thread.currentThread().getName() + " use time:" + (endTime - startTime));
	}
}

class MyTimeUtil {
	public static long START_TIME = 0;
	public static long END_TIME = 0;
}

输出:

Thread name:Thread-0 use time:3000
Thread name:Thread-1 use time:3000
application use time:6000

2.结论

从输出可以看见,当我们使用同步方法的时候,特别是同步步骤非常多,而且某些步骤需要时间非常长的时候,就会出现上面的隐患,性能非常低下。

而且,其实我们在同步的时候,前后的查询不一定要求这么强的数据一致性,只需要中间更新的部分要求强一致性即可。

因此,我们将在下一章节引出另一个同步方式来解决这个隐患--同步代码块。

总结:这一章节我们主要讨论了同步方法的隐患。

这一章节就到这里,谢谢

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

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

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

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

时间: 2024-11-12 13:17:07

从头认识多线程-2.7 同步方法的隐患的相关文章

从头认识多线程-2.17 同步方法与同步静态代码块持有的是不同的锁

这一章节我们来讨论一下同步方法与同步静态代码块持有的是不同的锁. 代码清单: package com.ray.deepintothread.ch02.topic_18; /** * * @author RayLee * */ public class SynchClass { public static void main(String[] args) throws InterruptedException { MyService myService = new MyService(); Thr

从头认识多线程-2.8 缓解同步方法的隐患-同步代码块

这一章节我们来讨论一下缓解同步方法的隐患-同步代码块. 1.思路:把同步方法,降低同步的粒度,同步到代码块 2.根据上一章节的例子,我们把代码修改一下 (1)第一种方法,把同步标记移到更新的那一栏里面去,一般来说大部分都是更新的时候需要同步数据 package com.ray.deepintothread.ch02.topic_9; /** * 从头认识多线程-2.8 缓解同步方法的隐患-同步代码块<br> * * @author RayLee * */ public class Relief

四、java多线程核心技术——synchronized同步方法与synchronized同步快

一.synchronized同步方法 论:"线程安全"与"非线程安全"是多线程的经典问题.synchronized()方法就是解决非线程安全的. 1.方法内的变量为线程安全 public void addI(String username) { try { int num = 0; \\方法内的变量为线程安全 if (username.equals("a")) { num = 100; System.out.println("a set

多线程编程——线程同步方法

1.五种方式 1.1 synchronized同步方法 使用synchronized关键字修饰的方法.java每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法.在调用该方法前,需获取内置锁,否则就会处于阻塞状态. 如:public synchronized void save(){} 注:当synchronized关键字修饰静态方法时,会锁住整个类 1.2 synchronized同步代码块 即有synchronized关键字修饰的语句块.被该关键字修饰的语句块会自动被加上内

从头认识多线程-2.2 synchronized持有对象锁与类锁的相同点

这一章节我们来讨论一下synchronized持有对象锁与类锁的相同点. 1.当所有方法都不使用同步的时候 代码清单 package com.ray.deepintothread.ch02.topic_2; public class SynchInstance1 { public static void main(String[] args) throws InterruptedException { MyTestObjectOne myTestObjectOne = new MyTestObj

java 多线程 synchronized块 同步方法

synchronized关键字又称同步锁 当方法执行完后,会自动释放锁,只有一个线程能进入此方法 看看以下的各种例子对synchronized的详细解释 1.是否加synchronized关键字的不同 1 public class ThreadTest { 2 3 public static void main(String[] args) { 4 Example example = new Example(); 5 6 Thread t1 = new Thread1(example); 7 T

多线程(二) 线程的安全隐患

有了多线程就有了资源竞争,当多个线程对同一资源进行操作时就容易出现安全隐患. 下面举一个卖票的例子来说明线程的安全隐患 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @interface ViewController () @property (assign, nonatomic)NSInteger ticke

从头认识多线程-3.2 使用volatile声明的变量的写操作是非原子性的

这一章节我们来讨论一下使用volatile声明的变量的各种操作是非原子性的. 1.上一章节我们已经提到,volatile把工作内存里面变量的改变同步到主内存, 使得各个线程能够把该变量当成是整体的状态控制 2.但是,使用volatile声明的变量的写操作是非原子性的 代码清单: package com.ray.deepintothread.ch03.topic_2; public class VolatileTest extends Thread { private volatile int i

从头认识多线程-4.1 对象的发布(Publish)、逸出(Escape)以及逸出的解决方案

这一章节我们来讨论一下对象的发布与逸出. 其实在前两个章节我们都有想应的讨论,只不过有一些不用补充的问题,我将会放到这个章节里面去. 1.发布(Publish) 当一个对象能够给其他代码引用. package com.ray.deepintothread.ch04.topic_1; import java.util.HashMap; public class Publish { private HashMap<String, Object> map = null; public HashMap