据我所知,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/