synchronized 方法对 非synchronized方法的影响

Posted /*小神经*/

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized 方法对 非synchronized方法的影响相关的知识,希望对你有一定的参考价值。

StringBuilder是线程不安全的类。

StringBuffer是线程安全的,因为它里面的方法加了synchronized。

今天写了一段代码测试了一下:用循环开启10个线程,调用StringBuffer(StringBuilder)的append追加1 到 10 。

结果预期一样:线程不安全的StringBuilder会漏掉一些数字,

public static void main(String[] args) throws InterruptedException {
        StringBuffer buffer = new StringBuffer();
        StringBuilder builder = new StringBuilder();
        // 开启十个线程,分别对buffer 和 builder 操作        
        for(int i = 0; i < 10; i++) {
            int j = i;
            new Thread(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(500); //造成阻塞
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    builder.append(j);
                }
            }).start();
        }
        //等待以上操作完成
        Thread.sleep(1000);
        // 打印结果
        System.out.println("builder:"+builder);
    }

线程安全的StringBuffer则追加了全部10个数字:

public static void main(String[] args) throws InterruptedException {
    StringBuffer buffer = new StringBuffer();
    StringBuilder builder = new StringBuilder();
    // 开启十个线程,分别对buffer 和 builder 操作        
    for(int i = 0; i < 10; i++) {
        int j = i;
        new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(500); //造成阻塞
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                buffer.append(j);
            }
        }).start();
    }
    //等待以上操作完成
    Thread.sleep(1000);
    // 打印结果
    System.out.println("buffer:"+buffer);
}

 

这时:如果我同时操作builder和buffer,且先调用buffer的append,这时每次操作因为builder和buffer在同一个线程,builder的方法因为buffer阻塞了线程而被变成“同步”的方法,同样append了10个数字

public static void main(String[] args) throws InterruptedException {
    StringBuffer buffer = new StringBuffer();
    StringBuilder builder = new StringBuilder();
    // 开启十个线程,分别对buffer 和 builder 操作        
    for(int i = 0; i < 10; i++) {
        int j = i;
        new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(500); //造成阻塞
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                buffer.append(j);
                builder.append(j);
            }
        }).start();
    }
    //等待以上操作完成
    Thread.sleep(1000);
    // 打印结果
    System.out.println("buffer:"+buffer);
    System.out.println("builder:"+builder);
}

 

以上是关于synchronized 方法对 非synchronized方法的影响的主要内容,如果未能解决你的问题,请参考以下文章

总结:一文死磕 synchronized 和 AQS 系

synchronized的四种用法

Java基础之线程synchronized关键字

synchronized 方法对 非synchronized方法的影响

锁的总结

锁的总结