java - 如何破坏 StringBuilder 线程安全(示例不安全代码很有可能被破坏)

标签 java multithreading concurrency

据我所知,StringBuilder 不是线程安全的。

我想编写一个打破 StringBuilder 与数据竞争的示例。

我的代码:

public class Task4 {
    static StringBuilder stringBuilder = new StringBuilder("");
    static long N = 1000000;

    public static void main(String[] args) {
        MyStringBufferThreadReader myStringBufferThreadReader = new MyStringBufferThreadReader(stringBuilder);
        MyStringBufferThreadWriter myStringBufferThreadWriter = new MyStringBufferThreadWriter(stringBuilder);
        new Thread(myStringBufferThreadReader).start();
        new Thread(myStringBufferThreadWriter).start();
    }
}

class MyStringBufferThreadReader implements Runnable {
    StringBuilder stringBuilder;

    public MyStringBufferThreadReader(StringBuilder stringBuffer) {
        this.stringBuilder = stringBuffer;
    }

    @Override
    public void run() {
        for (int i = 0; i < Task4.N; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("READ:  " + stringBuilder);
        }
    }
}

class MyStringBufferThreadWriter implements Runnable {
    static StringBuilder stringBuilder;

    public MyStringBufferThreadWriter(StringBuilder stringBuffer) {
        this.stringBuilder = stringBuffer;
    }

    @Override
    public void run() {
        for (int i = 0; i < Task4.N; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stringBuilder.append(i);
            System.out.println("WROTE: " + stringBuilder);

        }
    }
}

我是否做错了什么破坏了 StringBuilder 或者我只是幸运并且可能会发现问题?

最佳答案

谢谢 – @Vivin Paliath

public class Task4 {
    static StringBuilder stringBuilder = new StringBuilder("");
    static final StringBuilder SEPARATOR = new StringBuilder("/");

    static long N = 1000000;

    public static void main(String[] args) {
        MyStringBufferThreadReader myStringBufferThreadReader = new MyStringBufferThreadReader(stringBuilder);
        MyStringBufferThreadWriter myStringBufferThreadWriter = new MyStringBufferThreadWriter(stringBuilder);
        new Thread(myStringBufferThreadReader).start();
        new Thread(myStringBufferThreadWriter).start();
        new Thread(myStringBufferThreadReader).start();
        new Thread(myStringBufferThreadWriter).start();
    }
}

class MyStringBufferThreadReader implements Runnable {
    StringBuilder stringBuilder;

    public MyStringBufferThreadReader(StringBuilder stringBuffer) {
        this.stringBuilder = stringBuffer;
    }

    @Override
    public void run() {
        for (int i = 0; i < Task4.N; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("READ:  " + stringBuilder);
        }
    }
}

class MyStringBufferThreadWriter implements Runnable {
    static StringBuilder stringBuilder;

    public MyStringBufferThreadWriter(StringBuilder stringBuffer) {
        this.stringBuilder = stringBuffer;
    }

    @Override
    public void run() {
        for (int i = 0; i < Task4.N; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("WROTE: " + stringBuilder.append(i).append(Task4.SEPARATOR));

        }
    }
}

输出:

READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
READ:  
WROTE: 0/
WROTE: 0/0/
READ:  0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
READ:  0/0/
WROTE: 0/0/11/
READ:  0/0/1
WROTE: 0/0/11
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
READ:  0/0/11/
WROTE: 0/0/11/2/ 
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
WROTE: 0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
READ:  0/0/11/2/ /
WROTE: 0/0/11/2/ /3/
READ:  0/0/11/2/ /
WROTE: 0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/
READ:  0/0/11/2/ /3/4/
WROTE: 0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/
WROTE: 0/0/11/2/ /3/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/
READ:  0/0/11/2/ /3/4/4/5
WROTE: 0/0/11/2/ /3/4/4/5/5/
WROTE: 0/0/11/2/ /3/4/4/5/
READ:  0/0/11/2/ /3/4/4/5
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
READ:  0/0/11/2/ /3/4/4/5/5/
WROTE: 0/0/11/2/ /3/4/4/5/5/6/ 
WROTE: 0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
READ:  0/0/11/2/ /3/4/4/5/5/6// 
WROTE: 0/0/11/2/ /3/4/4/5/5/6// 7/
WROTE: 0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
READ:  0/0/11/2/ /3/4/4/5/5/6// 7/7/
....

关于java - 如何破坏 StringBuilder 线程安全(示例不安全代码很有可能被破坏),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31681662/

相关文章:

java - 如何从 .csv 文件中拆分数据集以用于 Java 中的训练和测试?

android - 在 MPAndroidChart 中绘制图形完成时如何接收回调?

java - 如何对我现有的 javafx 应用程序进行多线程处理

go - 执行 goroutine 时的并发与并行

multithreading - 在顺序执行的线程中使用ArrayBuffer?

Map 的 Java 泛型问题

Java:通过名称调用和访问数组,该名称存储在不同数组或变量内的字符串中

java.lang.UnsatisfiedLinkError : no frmjapi in java. 库.path

windows-vista - 在Windows Vista中,线程计划程序在哪个IRQL上运行?

java - 如何让进度条 Swing 进度?