学习笔记——JAVA线程<4>线程的同步

来源:互联网 发布:武汉java讲师 编辑:程序博客网 时间:2024/06/03 11:18

同步也称为并发 因为有多个线程访问同一份资源 所以要确保资源安全 加上同步后就可以线程安全
synchronized //锁
同步
一,同步方法

谁先抢到synchronized谁先进其余的等待

package study;/** *  * @author http://blog.csdn.net/thewaiting/ * */public class ThreadDome implements Runnable {    //共同使用i资源    private int i = 5;    private boolean flag = true;    @Override    public void run() {         while (flag) {         //text1();            text2();        }    }    public static void main(String[] args) {            // 1),创建真实角色        ThreadDome td1 = new ThreadDome();        // 2),创建代理角色+真实角色的引用        Thread t1 = new Thread(td1, "线程 1 ");        Thread t2 = new Thread(td1, "线程 2 ");        // 3),调用.star()方法 启动线程        t1.start();         t2.start();    }    public synchronized void text2() {          if (i <= 0) {              flag = false;              return;//方法return             }             try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }             System.out.println(Thread.currentThread().getName() + i--);    }    public void text1() {           if (i <= 0) {            flag = false;             return;//方法return           }           try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }           System.out.println(Thread.currentThread().getName() + i--);    }}text()1运行结果截取线程 1 0线程 2 -1text()2运行结果截取线程 2 2线程 2 1

二,同步块
谁先得到synchronized谁先进入块其余的等待
synchronized(引用类型|this|类.class ){
上锁的
}

    public void text3() {        synchronized (this) {            if (i <= 0) {                flag = false;                return;// 方法return            }            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName() + i--);        }    }

错误的锁定
锁定范围过小

// 锁定范围过小    public void text4() {        synchronized (this) {            if (i <= 0) {                flag = false;                return;// 方法return            }        }        try {            Thread.sleep(100);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName() + i--);    }

锁定资源不正确 要锁定进来获取资源的对象

//// 锁定资源不正确 要锁定进来获取资源的对象    public void text5() {        synchronized ((Integer)i) {            if (i <= 0) {                flag = false;                return;// 方法return            }        }        try {            Thread.sleep(100);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName() + i--);    }

线程安全的效率慢

synchronized单利模式

package study;/** * 单例设计模式:确保一个类只有一个对象 类里面创建 * @author http://blog.csdn.net/thewaiting/ * */public class ThreadDome {    public static void main(String[] args) {        ScThread scThread1 = new ScThread(100);          ScThread scThread2 = new ScThread(500);          scThread1.start();          scThread2.start();    }}class ScThread extends Thread{    private long time;    public ScThread(long time) {        this.time = time;    }    @Override    public void run() {        try {            System.out.println(Thread.currentThread().getName()+"创建"+Sc.getInstance(time));        } catch (InterruptedException e) {            // TODO 自动生成的 catch 块            e.printStackTrace();        }    }}//确保一个类只有一个对象 懒汉式//1,构造器私有化,避免外部直接创造对象//2,声明一个私有的静态对象//3,创建一个对外的公共的静态方法访问该变量 如果变量没有对象,创建该对象class Sc{    //声明一个私有的静态对象    private static  Sc instance = null;//懒得创建对象使用时再创建对象   对应有饿汉式    //构造器私有化,避免外部直接创造对象    private Sc() {    }    //创建一个对外的公共的静态方法访问该变量 如果变量没有对象,创建该对象    public static Sc getInstance(long time) throws InterruptedException {        if (null==instance) {            Thread.sleep(time);//故意放大发生错误的概率            instance = new Sc();        }        return instance;    }}运行结果Thread-0创建study.Sc@6b20e4e1Thread-1创建study.Sc@7bedda88
修改为synchronized锁定方法public static synchronized Sc getInstance(long time) throws InterruptedException 运行结果Thread-0创建study.Sc@7bedda88Thread-1创建study.Sc@7bedda88

锁定块

//双重检查//创建一个对外的公共的静态方法访问该变量 如果变量没有对象,创建该对象    public static Sc getInstance(long time) throws InterruptedException {        if (null == instance) {//如果存在就返回instance效率提高 提高已经存在的对象的访问效率            synchronized (Sc.class) {// 锁定字节码信息                if (null == instance) {                    Thread.sleep(time);// 故意放大发生错误的概率                    instance = new Sc();                }            }        }        return instance;    }运行结果Thread-1创建study.Sc@12341ad6Thread-0创建study.Sc@12341ad6
原创粉丝点击