博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java多线程基本概述(三)——同步块
阅读量:6273 次
发布时间:2019-06-22

本文共 7634 字,大约阅读时间需要 25 分钟。

1.1、synchronized方法的弊端

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-0end taskbegin task长时间处理任务后从远程返回的值1 threadName=Thread-1长时间处理任务后从远程返回的值2 threadName=Thread-1end task耗时:6

当把同步方法改为同步代码块时,

package mytask;import commonutils.CommonUtils;public class Task {    private String getData1;    private String getData2;    public  void doLongTimeTask() {        synchronized(Task.class){            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();            }        }            }}

输出结果:

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

可见,并没有提升效率,这是因为锁定的范围比较广,所以效果和锁方法的差别并不是太。那么可以缩小边界区,也就是资源真正开始竞争的地方。因为类中的成员变量才是资源的竞争对象,所以需要在访问这些变量的地方进行锁定。那么代码改为如下:

package mytask;import commonutils.CommonUtils;public class Task {    private String getData1;    private String getData2;    public  void doLongTimeTask() {                    try {                System.out.println("begin task");                Thread.sleep(3000);                getData1 = "长时间处理任务后从远程返回的值1 threadName="                        + Thread.currentThread().getName();                getData2 = "长时间处理任务后从远程返回的值2 threadName="                        + Thread.currentThread().getName();                synchronized(Task.class){                    System.out.println(getData1);                    System.out.println(getData2);                }                System.out.println("end task");            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }}

输出结果:

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

这时候可以看到时间已经减小了,这就出现一部分同步,一部分异步了。如何验证是真的一半同步一半异步呢?

package mytask;public class Task {    public void doLongTimeTask() {        for (int i = 0; i < 100; i++) {            System.out.println("nosynchronized threadName="                    + Thread.currentThread().getName() + " i=" + (i + 1));        }        System.out.println("");        synchronized (this) {            for (int i = 0; i < 100; i++) {                System.out.println("synchronized threadName="                        + Thread.currentThread().getName() + " i=" + (i + 1));            }        }    }}

输出结果:

=================================非同步块异步执行nosynchronized threadName=Thread-0 i=1nosynchronized threadName=Thread-1 i=1nosynchronized threadName=Thread-0 i=2nosynchronized threadName=Thread-1 i=2nosynchronized threadName=Thread-0 i=3nosynchronized threadName=Thread-1 i=3nosynchronized threadName=Thread-0 i=4nosynchronized threadName=Thread-1 i=4nosynchronized threadName=Thread-0 i=5nosynchronized threadName=Thread-1 i=5nosynchronized threadName=Thread-0 i=6nosynchronized threadName=Thread-1 i=6nosynchronized threadName=Thread-0 i=7nosynchronized threadName=Thread-1 i=7nosynchronized threadName=Thread-0 i=8nosynchronized threadName=Thread-1 i=8=================================同步块同步执行synchronized threadName=Thread-1 i=85synchronized threadName=Thread-1 i=86synchronized threadName=Thread-1 i=87synchronized threadName=Thread-1 i=88synchronized threadName=Thread-1 i=89synchronized threadName=Thread-1 i=90synchronized threadName=Thread-1 i=91synchronized threadName=Thread-1 i=92synchronized threadName=Thread-1 i=93synchronized threadName=Thread-1 i=94synchronized threadName=Thread-1 i=95synchronized threadName=Thread-1 i=96synchronized threadName=Thread-1 i=97synchronized threadName=Thread-1 i=98synchronized threadName=Thread-1 i=99synchronized threadName=Thread-1 i=100synchronized threadName=Thread-0 i=1synchronized threadName=Thread-0 i=2synchronized threadName=Thread-0 i=3synchronized threadName=Thread-0 i=4synchronized threadName=Thread-0 i=5synchronized threadName=Thread-0 i=6synchronized threadName=Thread-0 i=7synchronized threadName=Thread-0 i=8synchronized threadName=Thread-0 i=9synchronized threadName=Thread-0 i=10synchronized threadName=Thread-0 i=11synchronized threadName=Thread-0 i=12synchronized threadName=Thread-0 i=13synchronized threadName=Thread-0 i=14synchronized threadName=Thread-0 i=15synchronized threadName=Thread-0 i=16

 

转载于:https://www.cnblogs.com/soar-hu/p/6723829.html

你可能感兴趣的文章
Dos命令删除添加新服务
查看>>
C#.NET常见问题(FAQ)-索引器indexer有什么用
查看>>
hadoop YARN配置参数剖析—MapReduce相关参数
查看>>
Java 正则表达式详细使用
查看>>
【ADO.NET】SqlBulkCopy批量添加DataTable
查看>>
SqlServer--bat批处理执行sql语句1-osql
查看>>
Linux系列教程(十八)——Linux文件系统管理之文件系统常用命令
查看>>
laravel安装初体验
查看>>
用yum查询想安装的软件
查看>>
TIJ -- 吐司BlockingQueue
查看>>
数据库分页查询
查看>>
[编程] C语言枚举类型(Enum)
查看>>
[Javascript] Compose multiple functions for new behavior in JavaScript
查看>>
ASP.NET MVC性能优化(实际项目中)
查看>>
ES6里关于类的拓展(一)
查看>>
零元学Expression Blend 4 - Chapter 46 三分钟快速充电-设定Margin的小撇步
查看>>
Format Conditions按条件显示表格记录
查看>>
RichTextBox指定全部文字显示不同颜色及部分文字高亮颜色显示
查看>>
mysql优化----explain的列分析
查看>>
Python正则表达式
查看>>