文章来源:http://blog.sina.com.cn/s/blog_6560efc9010185ef.html
当我们查看JDK API的时候,总会发现一些类说明写着,线程安全或者线程不安全,比如说StringBuilder中,有这么一句,“将StringBuilder
StringBuffer
。 ”,那么下面手动创建一个线程不安全的类,然后在多线程中使用这个类,看看有什么效果。
- public
class Count { -
private int num; -
public void count() { -
for(int i = 1; i <= 10; i++) { -
num += i; -
} -
System.out.println(Thread.currentThread().getName() + "-" + num); -
} - }
- public
class ThreadTest { -
public static void main(String[] args) { -
Runnable runnable = new Runnable() { -
Count count = new Count(); -
public void run() { -
count.count(); -
} -
}; -
for(int i = 0; i < 10; i++) { -
new Thread(runnable).start(); -
} -
} - }
- Thread-0-55
- Thread-1-110
- Thread-2-165
- Thread-4-220
- Thread-5-275
- Thread-6-330
- Thread-3-385
- Thread-7-440
- Thread-8-495
- Thread-9-550
- public
class Count { -
public void count() { -
int num = 0; -
for(int i = 1; i <= 10; i++) { -
num += i; -
} -
System.out.println(Thread.currentThread().getName() + "-" + num); -
} - }
- public
class ThreadTest4 { -
public static void main(String[] args) { -
Runnable runnable = new Runnable() { -
public void run() { -
Count count = new Count(); -
count.count(); -
} -
}; -
for(int i = 0; i < 10; i++) { -
new Thread(runnable).start(); -
} -
} - }
上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的,为什么会产生这样的结果呢,因为建立的Count对象是线程共享的,一个线程改变了其成员变量num值,下一个线程正巧读到了修改后的num,所以会递增输出。
- public
class TraditionalThreadSynchro nized { -
public static void main(String[] args) { -
final Outputter output = new Outputter(); -
new Thread() { -
public void run() { -
output.output("zhangsan"); -
}; -
}.start(); -
new Thread() { -
public void run() { -
output.output("lisi"); -
}; -
}.start(); -
} - }
- class
Outputter { -
public void output(String name) { -
// TODO 为了保证对name的输出不是一个原子操作,这里逐个输出name的每个字符 -
for(int i = 0; i < name.length(); i++) { -
System.out.print(name.charAt(i)); -
} -
} - }
- zhlainsigsan
- synchronized
(this) { -
for(int i = 0; i < name.length(); i++) { -
System.out.print(name.charAt(i)); -
} - }
- Object
lock = new Object(); - synchronized
(lock) { -
for(int i = 0; i < name.length(); i++) { -
System.out.print(name.charAt(i)); -
} - }
- public
synchronized void output(String name) { -
// TODO 线程输出方法 -
for(int i = 0; i < name.length(); i++) { -
System.out.print(name.charAt(i)); -
} - }
- class
Test { -
static int i = 0, j = 0; -
static void one() { -
i++; -
j++; -
} -
static void two() { -
System.out.println("i=" + i + " j=" + j); -
} - }
- class
Test { -
static volatile int i = 0, j = 0; -
static void one() { -
i++; -
j++; -
} -
static void two() { -
System.out.println("i=" + i + " j=" + j); -
} - }