博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
四、java多线程核心技术——synchronized同步方法与synchronized同步快
阅读量:5118 次
发布时间:2019-06-13

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

一、synchronized同步方法

论:“线程安全”与“非线程安全”是多线程的经典问题。synchronized()方法就是解决非线程安全的。

1、方法内的变量为线程安全

public void addI(String username) {        try {            int num = 0;     \\方法内的变量为线程安全            if (username.equals("a")) {                num = 100;                System.out.println("a set over!");                Thread.sleep(2000);            } else {                num = 200;                System.out.println("b set over!");            }            System.out.println(username + " num=" + num);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }

2、实例变量非线程安全

public class HasSelfPrivateNum {    private int num = 0;    \\实例变量非线程安全    public void addI(String username) {        try {            if (username.equals("a")) {                num = 100;                System.out.println("a set over!");                Thread.sleep(2000);            } else {                num = 200;                System.out.println("b set over!");            }            System.out.println(username + " num=" + num);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

解决方法: 方法前加synchronized关键字。

public class HasSelfPrivateNum {    private int num = 0;    synchronized public void addI(String username) {       ..............    }}

3、多个对象多个锁

HasSelfPrivateNum.java

public class HasSelfPrivateNum {    private int num = 0;    synchronized public void addI(String username) {        try {            if (username.equals("a")) {                num = 100;                System.out.println("a set over!");                Thread.sleep(2000);            } else {                num = 200;                System.out.println("b set over!");            }            System.out.println(username + " num=" + num);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

ThreadA

public class ThreadA extends Thread {            private HasSelfPrivateNum numRef;            public ThreadA(HasSelfPrivateNum numRef) {            super();            this.numRef = numRef;        }            @Override        public void run() {            super.run();            numRef.addI("a");        }        }
ThreadB
public class ThreadB extends Thread {    private HasSelfPrivateNum numRef;    public ThreadB(HasSelfPrivateNum numRef) {        super();        this.numRef = numRef;    }    @Override    public void run() {        super.run();        numRef.addI("b");    }}

RUN

public class Run {    public static void main(String[] args) {        HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();        HasSelfPrivateNum numRef2 = new HasSelfPrivateNum();        ThreadA athread = new ThreadA(numRef1);        athread.start();        ThreadB bthread = new ThreadB(numRef2);        bthread.start();    }}

结果:创建了2个业务实例,产生2个锁,所以运行结果是异步的。同步为synchronized  异步:asynchronized

4、synchronized 锁重入

                   当一个线程得到一个对象锁时,再次请求该对象锁时是可以再次得到该对象的锁的。继承关系也可重入锁。

                   当一个线程执行发生异常时,其持有的锁会自动释放。

                   同步不具有继承性。的在子类方法中添加synchronized的关键字。

public class HasSelfPrivateNum {    synchronized public void service1() {        System.out.println("service1");        service2();    }    synchronized public void service2() {        System.out.println("service2");        service3();    }    synchronized public void service3() {        System.out.println("service3");    }}
HasSelfPrivateNum.java
public class mYThread extends Thread {    @Override    public void run() {        HasSelfPrivateNum hspn=new HasSelfPrivateNum();        hspn.service1();        }   public static void main(String[] args) {       mYThread mYThread=new mYThread();       mYThread.start(); }}
mYThread.java

 二、synchronized同步快

    synchronized同步方法持有锁后,如果长时间不释放,那另一个线程就必须长时间等待。。这种情况下synchronized同步快来解决

使用方法如图:

                1、synchronized同步快之间具有同步性,当线程访问object的一个  synchronized(this)同步代码块时,其他线程对同一个object对象中所有其他的

synchronized(this)同步代码块的访问会被阻塞。

                2、synchronized(this)同步代码块是锁定当前对象的。

1、synchronized同步快解决同步方法效率低得弊端

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();        }    }}
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();    }}
MyThread1
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();    }}
MyThread2
public class CommonUtils {    public static long beginTime1;    public static long endTime1;    public static long beginTime2;    public static long endTime2;}
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));    }}
Run

修改Task

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();        }    }}
View Code

转载于:https://www.cnblogs.com/aGboke/p/6523365.html

你可能感兴趣的文章
引用 移植Linux到s3c2410上
查看>>
MySQL5.7开多实例指导
查看>>
[51nod] 1199 Money out of Thin Air #线段树+DFS序
查看>>
poj1201 查分约束系统
查看>>
Red and Black(poj-1979)
查看>>
分布式锁的思路以及实现分析
查看>>
腾讯元对象存储之文件删除
查看>>
jdk环境变量配置
查看>>
安装 Express
查看>>
包含列的索引:SQL Server索引的阶梯级别5
查看>>
myeclipse插件安装
查看>>
浙江省第十二届省赛 Beauty of Array(思维题)
查看>>
NOIP2013 提高组 Day1
查看>>
个人对vue生命周期的理解
查看>>
cocos2dx 3.x simpleAudioEngine 长音效被众多短音效打断问题
查看>>
存储(硬件方面的一些基本术语)
查看>>
观察者模式
查看>>
Weka中数据挖掘与机器学习系列之基本概念(三)
查看>>
Win磁盘MBR转换为GUID
查看>>
大家在做.NET B/S项目的时候多用什么设技术啊?
查看>>