synchronized 的弊端: 耗时过长解决方法:用同步代码块解决时间太长的弊端,但是同步代码块也是有弊端的

1 耗时过长 

package commonutils;
public class CommonUtils {
	public static long beginTime1;
	public static long endTime1;
	public static long beginTime2;
	public static long endTime2;
}
package mytask;
import commonutils.CommonUtils;
public class Task {
	private String getData1;
	private String getData2;
	public synchronized void doLongTimeTask() {
		try {
			System.out.println("begin task");
			Thread.sleep(3000);
			getData1 = "长时间处理任务后从远程返回的值1 threadName="
					+ Thread.currentThread().getName();
			getData2 = "长时间处理任务后从远程返回的值2 threadName="
					+ Thread.currentThread().getName();
			System.out.println(getData1);
			System.out.println(getData2);
			System.out.println("end task");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
package mythread;
import commonutils.CommonUtils;
import mytask.Task;
public class MyThread1 extends Thread {
	private Task task;
	public MyThread1(Task task) {
		super();
		this.task = task;
	}
	@Override
	public void run() {
		super.run();
		CommonUtils.beginTime1 = System.currentTimeMillis();
		task.doLongTimeTask();
		CommonUtils.endTime1 = System.currentTimeMillis();
	}
}
package mythread;
import commonutils.CommonUtils;
import mytask.Task;
public class MyThread2 extends Thread {
	private Task task;
	public MyThread2(Task task) {
		super();
		this.task = task;
	}
	@Override
	public void run() {
		super.run();
		CommonUtils.beginTime2 = System.currentTimeMillis();
		task.doLongTimeTask();
		CommonUtils.endTime2 = System.currentTimeMillis();
	}
}
package test;
import mytask.Task;
import mythread.MyThread1;
import mythread.MyThread2;
import commonutils.CommonUtils;
public class Run {
	public static void main(String[] args) {
		Task task = new Task();
		MyThread1 thread1 = new MyThread1(task);
		thread1.start();
		MyThread2 thread2 = new MyThread2(task);
		thread2.start();
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		long beginTime = CommonUtils.beginTime1;
		if (CommonUtils.beginTime2 < CommonUtils.beginTime1) {
			beginTime = CommonUtils.beginTime2;
		}
		long endTime = CommonUtils.endTime1;
		if (CommonUtils.endTime2 > CommonUtils.endTime1) {
			endTime = CommonUtils.endTime2;
		}
		System.out.println("耗时:" + ((endTime - beginTime) / 1000));
	}
}

结果:(耗时过长)

begin task
长时间处理任务后从远程返回的值1 threadName=Thread-0
长时间处理任务后从远程返回的值2 threadName=Thread-0
end task
begin task
长时间处理任务后从远程返回的值1 threadName=Thread-1
长时间处理任务后从远程返回的值2 threadName=Thread-1
end task
耗时:6

用同步代码块解决时间太长的弊端

package extthread;
import service.ObjectService;
public class ThreadA extends Thread {
	private ObjectService service;
	public ThreadA(ObjectService service) {
		super();
		this.service = service;
	}
	@Override
	public void run() {
		super.run();
		service.serviceMethod();
	}
}
package extthread;
import service.ObjectService;
public class ThreadB extends Thread {
	private ObjectService service;
	public ThreadB(ObjectService service) {
		super();
		this.service = service;
	}
	@Override
	public void run() {
		super.run();
		service.serviceMethod();
	}
}

 

package service;

public class ObjectService {

	public void serviceMethod() {
		try {
			synchronized (this) {
				long begintime = System.currentTimeMillis();
				System.out.println("begin time=" + begintime);
				Thread.sleep(2000);
				long end = System.currentTimeMillis();
				System.out.println("end    end=" + end);
				System.out.println((end- begintime)/1000);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
package test.run;
import service.ObjectService;
import extthread.ThreadA;
import extthread.ThreadB;
public class Run {
	public static void main(String[] args) {
		ObjectService service = new ObjectService();
		ThreadA a = new ThreadA(service);
		a.setName("a");
		a.start();
		ThreadB b = new ThreadB(service);
		b.setName("b");
		b.start();
	}
}

 结果

begin time=1533652853821
end    end=1533652855822
2
begin time=1533652855822
end    end=1533652857822
2

 这也引出了synchronized 代码块执行效率比synchronized 修饰方法要高

1 用同步代码块解决同步方法的弊端

package commonutils;
public class CommonUtils {
	public static long beginTime1;
	public static long endTime1;
	public static long beginTime2;
	public static long endTime2;
}
package mytask;
public class Task {
	private String getData1;
	private String getData2;
	public void doLongTimeTask() {
		try {
			System.out.println("begin task");
			Thread.sleep(3000);
			String privateGetData1 = "长时间处理任务后从远程返回的值1 threadName="
					+ Thread.currentThread().getName();
			String privateGetData2 = "长时间处理任务后从远程返回的值2 threadName="
					+ Thread.currentThread().getName();
			synchronized (this) {
				getData1 = privateGetData1;
				getData2 = privateGetData2;
			}
			
			System.out.println(getData1);
			System.out.println(getData2);
			System.out.println("end task");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
package mythread;
import commonutils.CommonUtils;
import mytask.Task;
public class MyThread1 extends Thread {
	private Task task;
	public MyThread1(Task task) {
		super();
		this.task = task;
	}
	@Override
	public void run() {
		super.run();
		CommonUtils.beginTime1 = System.currentTimeMillis();
		task.doLongTimeTask();
		CommonUtils.endTime1 = System.currentTimeMillis();
	}
}
package mythread;
import commonutils.CommonUtils;
import mytask.Task;
public class MyThread2 extends Thread {
	private Task task;
	public MyThread2(Task task) {
		super();
		this.task = task;
	}
	@Override
	public void run() {
		super.run();
		CommonUtils.beginTime2 = System.currentTimeMillis();
		task.doLongTimeTask();
		CommonUtils.endTime2 = System.currentTimeMillis();
	}
}
package test;
import mytask.Task;
import mythread.MyThread1;
import mythread.MyThread2;
import commonutils.CommonUtils;
public class Run {
	public static void main(String[] args) {
		Task task = new Task();
		MyThread1 thread1 = new MyThread1(task);
		thread1.start();
		MyThread2 thread2 = new MyThread2(task);
		thread2.start();
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		long beginTime = CommonUtils.beginTime1;
		if (CommonUtils.beginTime2 < CommonUtils.beginTime1) {
			beginTime = CommonUtils.beginTime2;
		}
		long endTime = CommonUtils.endTime1;
		if (CommonUtils.endTime2 > CommonUtils.endTime1) {
			endTime = CommonUtils.endTime2;
		}
		System.out.println("耗时:" + ((endTime - beginTime) / 1000));
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值