2.1.4同步方法与对象锁

来源:互联网 发布:扫描仪软件打不开 编辑:程序博客网 时间:2024/06/03 17:36

package cha02.execise04;/** * Created by sunyifeng on 17/9/20. */public class MyObject {    public void methodA() {        try {            System.out.println("开始方法A,线程名称:" + Thread.currentThread().getName());            Thread.sleep(5000);            System.out.println("结束方法A。");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
package cha02.execise04;/** * Created by sunyifeng on 17/9/20. */public class ThreadA extends Thread {    private MyObject object;    public ThreadA(MyObject object){        super();        this.object = object;    }    @Override    public void run(){        super.run();        object.methodA();    }}
package cha02.execise04;/** * Created by sunyifeng on 17/9/20. */public class ThreadB extends Thread {    private MyObject object;    public ThreadB(MyObject object){        super();        this.object = object;    }    @Override    public void run(){        super.run();        object.methodA();    }}
package cha02.execise04;/** * Created by sunyifeng on 17/9/20. */public class Run {    public static void main(String[] args) {        MyObject object = new MyObject();        //        ThreadA threadA = new ThreadA(object);        threadA.setName("A");        //        ThreadB threadB = new ThreadB(object);        threadB.setName("B");        //        threadB.start();        threadA.start();    }}
运行结果:

开始方法A,线程名称:B
开始方法A,线程名称:A
结束方法A。
结束方法A。

程序分析:

程序的执行时不同步的,在方法前加上同步之后。

package cha02.execise04;/** * Created by sunyifeng on 17/9/20. */public class MyObject {    synchronized public void methodA() {        try {            System.out.println("开始方法A,线程名称:" + Thread.currentThread().getName());            Thread.sleep(5000);            System.out.println("结束方法A。");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
运行结果:

开始方法A,线程名称:B
结束方法A。
开始方法A,线程名称:A
结束方法A。

程序分析:

1、加了同步关键字的程序一定是同步的(线程排队执行);

2、共享:只有共享的资源读写才需要同步,不共享没有同步必要。

再看一个栗子。

package cha02.execise05;/** * Created by sunyifeng on 17/9/20. */public class MyObject {    synchronized public void methodA() {        try {            System.out.println("开始methodA,线程名称:" + Thread.currentThread().getName());            Thread.sleep(5000);            System.out.println("结束methodA, 结束时间:" + System.currentTimeMillis());        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public void methodB() { // TODO:没有同步        try {            System.out.println("开始methodB,线程名称:" + Thread.currentThread().getName());            Thread.sleep(5000);            System.out.println("结束methodB,结束时间:" + System.currentTimeMillis());        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
package cha02.execise05;/** * Created by sunyifeng on 17/9/20. */public class ThreadA extends Thread {    private MyObject object;    public ThreadA(MyObject object){        super();        this.object = object;    }    @Override    public void run(){        super.run();        object.methodA();    }}

package cha02.execise05;/** * Created by sunyifeng on 17/9/20. */public class ThreadB extends Thread {    private MyObject object;    public ThreadB(MyObject object){        super();        this.object = object;    }    @Override    public void run(){        super.run();        object.methodB();    }}
package cha02.execise05;/** * Created by sunyifeng on 17/9/20. */public class Run {    public static void main(String[] args) {        MyObject object = new MyObject();        //        ThreadA threadA = new ThreadA(object);        threadA.setName("A");        //        ThreadB threadB = new ThreadB(object);        threadB.setName("B");        //        threadA.start();        threadB.start();    }}
运行结果:

开始methodA,线程名称:A
开始methodB,线程名称:B
结束methodB,结束时间:1507618795793
结束methodA,结束时间:1507618795793

程序分析:

线程A先持有了object的对象锁,但是线程B可以异步调用object的非同步方法。

将方法B加上同步。

synchronized public void methodB() {    try {        System.out.println("开始methodB,线程名称:" + Thread.currentThread().getName());        Thread.sleep(5000);        System.out.println("结束methodB,结束时间:" + System.currentTimeMillis());    } catch (InterruptedException e) {        e.printStackTrace();    }}

运行结果:

开始methodA,线程名称:A
结束methodA,结束时间:1507619170066
开始methodB,线程名称:B
结束methodB,结束时间:1507619175070
原创粉丝点击