Synchronized在多线程中的使用

来源:互联网 发布:ubuntu怎么安装php 编辑:程序博客网 时间:2024/05/22 00:30

同步多线程:当两个并发线程访问同一个对象object中的synchronized(this)同步代码块时,一段时间内只能有一个线程被执行,另一个必须等待当前线程执行完这个代码块以后才能执行改代码。

class Task{    public int i = 0;    public synchronized void changeI(){        System.out.println("begin task");        for(int j = 0; j < 5; j++){            System.out.print(i + "--" + Thread.currentThread().getName()+"  ");            i++;        }        System.out.println("\nend task");    }}
class ThreadA extends Thread{    Task task;    public ThreadA(Task task) {        // TODO Auto-generated constructor stub        this.task = task;    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        task.changeI();    }}
客户端执行类
public class SyschronizedTest {    public static void main(String[] args){        Task task = new Task();        ThreadA a = new ThreadA(task);        ThreadA b = new ThreadA(task);        a.start();        b.start();    }}
运行结果

这里写图片描述

用同步代码块解决同步方法的弊端
class TaskProblem{    private String getData1;    private String getData2;    public void doLongTimeTask() throws InterruptedException{        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");    }}
class ThreadProblem extends Thread{    TaskProblem task;    public ThreadProblem(TaskProblem task) {        // TODO Auto-generated constructor stub        this.task = task;    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        try {            task.doLongTimeTask();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
public class SynchronizedTestProblem {    public static void main(String[] args){        TaskProblem task = new TaskProblem();        ThreadProblem a = new ThreadProblem(task);        ThreadProblem b = new ThreadProblem(task);        a.start();        b.start();    }}
第一次运行:

这里写图片描述

第二次运行:

这里写图片描述

总结:当一个线程访问Object的一个synchronized同步代码块时,另一个线程仍然可以访问该object对象的非synchronized(this)同步代码块。

一半异步,一半同步

下面这个程序用来说明:不在synchronized块中就是异步执行,在synchronized块中的就是同步执行
class TaskAsync{    public void doLongTimeTask(){        for(int i = 0; i < 5; i++){            System.out.println("nosynchronized threadName = " + Thread.currentThread().getName() + " i=" + (i+1));        }        System.out.println("");        synchronized (this) {        for(int i = 0;i < 5; i++){            System.out.println("synchronized threadName=" + Thread.currentThread().getName() + " i=" + (i+1));        }        }    }}
class ThreadAsync extends Thread{    TaskAsync task;    public ThreadAsync(TaskAsync task) {        // TODO Auto-generated constructor stub        this.task = task;    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        task.doLongTimeTask();    }}
public class SynchronizedTestAsync {    public static void main(String[] args){        TaskAsync task = new TaskAsync();        ThreadAsync a = new ThreadAsync(task);        ThreadAsync b = new ThreadAsync(task);        a.start();        b.start();    }}
运行结果:

这里写图片描述

synchronized代码块之间的同步性
在使用同步synchronized(this)代码块时需要注意的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞,这说明synchronized使用的“对象监视器”是一个。

class ObjectService{    public void serviceMethodA() throws InterruptedException{        synchronized(this){            System.out.println("A begin time=" + System.currentTimeMillis());            Thread.sleep(2000);            System.out.println("A end end=" + System.currentTimeMillis());        }    }    public void serviceMethodB(){        synchronized(this){            System.out.println("B begin time=" + System.currentTimeMillis());            System.out.println("B end time=" + System.currentTimeMillis());        }    }}
class ThreadObjectA extends Thread{    private ObjectService service;    public ThreadObjectA(ObjectService service) {        // TODO Auto-generated constructor stub        this.service = service;    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        try {            service.serviceMethodA();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}class ThreadObjectB extends Thread{    private ObjectService service;    public ThreadObjectB(ObjectService service) {        // TODO Auto-generated constructor stub        this.service = service;    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        service.serviceMethodB();    }}
运行结果

这里写图片描述

验证同步synchronized(this)代码块是锁定当前对象的
和synchronized方法一样,synchronized(this)代码块也是锁定当前对象的。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 亚马逊仓库满了怎么办 医保不给报销怎么办 海信电视特别卡怎么办 在花呗上被骗了怎么办 西洋杜鹃掉叶子怎么办 苹果iap支付失败怎么办 此项目无法退款怎么办 及贷逾期一天怎么办 快贷逾期一天怎么办 燃气灶开关松了怎么办 厨房插座挨灶台怎么办 天然气灶费电池怎么办 国美东西买贵啦怎么办 饥荒咕咕鸟死了怎么办 收到催天下信息怎么办 对门邻居有白事怎么办 顺丰理赔不合理怎么办 手机店抽奖被骗怎么办 手机店投票被骗怎么办 锤子手机进水了怎么办 锤子手机无法关机怎么办 坚果pro2卡顿怎么办 兴隆破产兴隆卡怎么办 电脑开机键失灵怎么办 网上买冰箱售后怎么办 物流公司损坏了怎么办 白色充电器线脏了怎么办 卷尺缩不回去怎么办 在昆山怎么办电瓶车牌 网购遇到质量问题怎么办 洗衣机外壳坏了怎么办 8元飞享套餐下线怎么办 改光纤后传真机怎么办 网上预约迟到了怎么办 国地税合并局长怎么办? 信用卡申请条件不足怎么办 深户落亲戚房产怎么办准迁证 从深圳迁出户口怎么办 快递未送达签收怎么办 床垫用水洗后怎么办 轿车空调不制冷怎么办