美文网首页
java中synchronized几种使用方法

java中synchronized几种使用方法

作者: 跨界师 | 来源:发表于2018-01-12 23:19 被阅读248次

在使用synchronized方法时,我总结了使用的情形:
第一种情形:

/**
 * Created by zhangzheming on 2018/1/12.
 */

public class SyncDubbo1 {

    public synchronized void method1(){
        System.out.println("method1..");
        method2();
    }

    public synchronized void method2() {
        System.out.println("method2..");
        method3();
    }

    public synchronized void method3() {
        System.out.println("method3");
    }

    public static void main(String[] args){
        final SyncDubbo1 sd = new SyncDubbo1();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                sd.method1();
            }
        });
        t1.start();
    }
}
运行结果

从上面的运行结果可以看出:在嵌套方法中使用synchronized,多线程情况下是线程安全的。

第二种情况:

/**
 * Created by zhangzheming on 2018/1/12.
 */

public class syncDubbo2 {

    // 主类
    static class Main{
        public int i = 10;
        public synchronized void operationSup(){
            try {
                i--;
                System.out.println("Main print i= "+i);
                Thread.sleep(100);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    // 子类
    static class Sub extends Main{
        public synchronized void operationSub(){
            try{
                while (i>0){
                    i--;
                    System.out.println("Sub print i= "+i);
                    Thread.sleep(100);
                    this.operationSup();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Sub sub = new Sub();
                sub.operationSub();
            }
        });

        t1.start();
    }
}
运行结果

此种情形主要是说明两点:
(1)在出现父子类继承关系的情况下,父类的成员变量也可以被子类继承。
(2)在父类和子类都使用synchronized ,出现多线程情况下,是线程安全的。

synchronized 的使用出现异常情况下,如果遇到异常,我们也需要处理异常情况,请看下面的代码:

/**
 * Created by zhangzheming on 2018/1/12.
 */

public class SyncException {

    private int i = 0;

    public synchronized void operation(){
        while (true){
            try{
                i++;
                Thread.sleep(200);
                System.out.println(Thread.currentThread().getName()+", i=" + i);
                if (i%10 == 0){
                    Integer.parseInt("a");
                }
            }catch (InterruptedException e){
                e.printStackTrace();
                // (3) contiune;
                 //(2)System.out.println("log info i = "+i);
                //(1)throw new RuntimeException();
            }
        }
    }

    public static void main(String[] args){
        final SyncException se = new SyncException();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                se.operation();
            }
        },"t1");
        t1.start();
    }
}

这段代码其实将输出变量i的累加值,但是每逢遇到被10整除的数时,就会遇到异常现象,这种情况下,我们有三种解决办法:
(1)第一种办法:throw new RuntimeException(); 将运行异常抛出,这样程序就会停止下来,不会影响到后面的任务,比较适合任务之前有先后顺序的关联关系;
(2)第二种办法:System.out.println("log info i = "+i);将错误信息打印出来或者打印到日志中出,事后进行分析和修复。
(3)第三种办法:contiune; 那就是最坏的情况,忽略错误,不处理异常情况

不要使用String字符串加锁,这样会导致死循环产生
请看下面的例子:

package Thread;

/**
 * Created by zhangzheming on 2018/1/15.
 */

public class StringLock {

    public void method(){
        // 使用字符串当做对象
        synchronized ("字符串常量"){
            try{
                while (true){
                    System.out.println("当前线程:"+Thread.currentThread().getName()+"开始");
                    Thread.sleep(1000);
                    System.out.println("当前线程:"+Thread.currentThread().getName()+"结束");
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        final StringLock stringLock = new StringLock();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                stringLock.method();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                stringLock.method();
            }
        });


        t1.start();
        t2.start();
    }
}

运行结果

按照我们预想的,启动两个线程会在执行结果中产生两个线程交替进行,但是与实际结果不相同,这是为什么?

原因在于字符串属于引用类型,不管什么样的字符串都是一个类型对象,这样就导致了只有一个线程存在,回头想想其实要解决这个问题,就是满足synchronized 锁住的是对象就可以了,修改如下:

package Thread;

/**
 * Created by zhangzheming on 2018/1/15.
 */

public class StringLock {

    public void method(){
        // 使用字符串当做对象
        synchronized (new String("字符串常量")){
            try{
                while (true){
                    System.out.println("当前线程:"+Thread.currentThread().getName()+"开始");
                    Thread.sleep(1000);
                    System.out.println("当前线程:"+Thread.currentThread().getName()+"结束");
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        final StringLock stringLock = new StringLock();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                stringLock.method();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                stringLock.method();
            }
        });


        t1.start();
        t2.start();
    }
}

运行结果

相关文章

  • java中synchronized几种使用方法

    在使用synchronized方法时,我总结了使用的情形:第一种情形: 从上面的运行结果可以看出:在嵌套方法中使用...

  • synchronized使用及原理

    简介 使用方法 java中每一个对象都可以作为锁,这是实现synchronized的基础,synchronized...

  • synchronized介绍

    synchronized: synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种: ...

  • synchronized

    synchronized synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种: 修...

  • 笔记

    java中有哪几种锁? 1.有synchronized和lock两种锁,synchronized是java的...

  • Java并发编程:synchronized和锁优化

    1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的...

  • 浅谈java内置锁synchronized

    1、synchronized使用 synchronized是java提供的关键字,用来实现同步,主要用法有以下几种...

  • 2018-05-11 JAVA

    1 java同步几种方法?threadlocal怎么实现。 java的同步机制 1.synchronized; 2...

  • Synchronized ReentrantLock Volat

    Synchronized Synchronized 简介 synchronized实现同步的基础:java中每个对...

  • 14 Java虚拟机实现 synchronized

    java 中的 synchronized 运行 在 Java 中,我们经常用 synchronized 关键字对程...

网友评论

      本文标题:java中synchronized几种使用方法

      本文链接:https://www.haomeiwen.com/subject/mfeqoxtx.html