下载资源 jar;https://repo1.maven.org/maven2/org/lucee/jcip-annotations/1.0.0/jcip-annotations-1.0.0.jar
添加 jar 到程序中
1. 线程不安全
多个线程中的操作执行顺序是不可预测的
非线程安全的序列生成器
1 2 3 4 5 6 7 8 9 10 11 12
| @NotThreadSafe class UnsafeSequence { private int value;
public UnsafeSequence(int value) { this.value = value; }
public int next() { return this.value++; } }
|
创建3个线程进行测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class UnsafeSequenceDemo { public static void main(String[] args) { UnsafeSequence unsafeSequence = new UnsafeSequence(100);
MyThread thread = new MyThread(unsafeSequence); Thread myThread1 = new Thread(thread, "线程1"); Thread myThread2 = new Thread(thread, "线程2"); Thread myThread3 = new Thread(thread, "线程3");
myThread1.start(); myThread2.start(); myThread3.start(); } }
class MyThread implements Runnable {
private UnsafeSequence unsafeSequence;
public MyThread(UnsafeSequence unsafeSequence) { this.unsafeSequence = unsafeSequence; }
@Override public void run() { System.out.println(Thread.currentThread().getName() + "------------------ " + unsafeSequence.next() + " ------------------"); } }
|
output:
1 2 3
| 线程2------------------ 100 ------------------ 线程1------------------ 100 ------------------ 线程3------------------ 101 ------------------
|
原因分析,可能情况:
线程2
启动,value=100 进行输出 100
线程1
启动,value=100 进行输出 100
线程2
value++,value=101
线程3
启动,value=101 进行输出 101
线程1
、线程3
也进行 value++,value=103
2. 线程安全
线程安全的数值序列生成器
1 2 3 4 5 6 7 8 9 10 11 12 13
| @ThreadSafe class Sequence { @GuardedBy("this") private int value;
public Sequence(int value) { this.value = value; }
public synchronized int next() { return this.value++; } }
|
创建3个线程进行测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class SequenceDemo { public static void main(String[] args) { Sequence sequence = new Sequence(100);
MeThread thread = new MeThread(sequence); Thread meThread1 = new Thread(thread, "线程1"); Thread meThread2 = new Thread(thread, "线程2"); Thread meThread3 = new Thread(thread, "线程3");
meThread1.start(); meThread2.start(); meThread3.start(); } }
class MeThread implements Runnable {
private Sequence sequence;
public MeThread(Sequence sequence) { this.sequence = sequence; }
@Override public void run() { System.out.println(Thread.currentThread().getName() + "------------------ " + sequence.next() + " ------------------"); } }
|
output:
1 2 3
| 线程1------------------ 100 ------------------ 线程2------------------ 101 ------------------ 线程3------------------ 102 ------------------
|