上QQ阅读APP看书,第一时间看更新
2.2.1 synchronized方法的弊端
为了证明用synchronized关键字声明方法时是有弊端的,下面创建t5项目来进行测试。
文件Task.java代码如下:
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(); } } }
用synchronized声明方法时,放在public之后与放在public之前没有区别。
文件CommonUtils.java代码如下:
package commonutils; public class CommonUtils { public static long beginTime1; public static long endTime1; public static long beginTime2; public static long endTime2; }
文件MyThread1.java代码如下:
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(); } }
文件MyThread2.java代码如下:
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(); } }
文件Run.java代码如下:
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)); } }
程序运行结果如图2-20所示。
图2-20 大约6秒后程序运行结束
通过使用synchronized关键字来声明方法,从运行的时间上来看,弊端突现,可以使用synchronized同步块解决类似问题。