两个线程交替打印1-100,列举以下几种方法:

  1. synchronized+objectwait()等待,notify() 唤醒
  2. Lock-condition(条件变量):c1.signalAll() 唤醒,c2.await() 等待
  3. volatile 修饰的变量,通过值控制(可以是boolean,或者是数字类型)
  4. Semaphore(信号量),acquire()获取许可,release()释放许可;
  5. CyclicBarrier(循环栅栏),await() 使等待
  6. AtomicBoolean,基于cas机制实现线程交替打印
  7. LockSupportpark()阻塞当前线程、unpark(Thread t) 释放t线程,设置锁标志位

Object(等待+唤醒)

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
31
32
33
34
/**
* <b> 多线程交替打印
* <p> 通过Object的 wait() 和 notify() 方法,需要借助锁实现,如 synchronized
*
* @Author He.hp
* @Email haeng2030@gmail.com
* @Date 2024/11/21 21:29
*/
public class WaitNotifyStagger {
private static final Object o1 = new Object();
private volatile int num = 0;

private void printf() {
do {
synchronized (o1) {
o1.notify();

System.out.println(Thread.currentThread().getName() + "-" + (++num));
try {
o1.wait(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}while (num < 100);
}

public static void main(String[] args) {
WaitNotifyStagger threadPrint = new WaitNotifyStagger();

new Thread(threadPrint::printf, "A").start();
new Thread(threadPrint::printf, "B").start();
}
}

Condition(条件变量)

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
31
32
33
34
35
public class ThreadStaggerByCondition {
private static final Lock lock = new ReentrantLock();
private static final ExecutorService threadPool = Executors.newFixedThreadPool(3);
private static int num = 0;

public void print(Condition curr, Condition next) {
do {
try {
lock.lockInterruptibly();
next.signal();

System.out.println(Thread.currentThread().getName() + "-" + (++num));

curr.await(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} while (num < 90);
}

public static void main(String[] args) {
ThreadStaggerByCondition threadPrint2 = new ThreadStaggerByCondition();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();

threadPool.submit(() -> threadPrint2.print(condition1, condition2));
threadPool.submit(() -> threadPrint2.print(condition2, condition3));
threadPool.submit(() -> threadPrint2.print(condition3, condition1));

threadPool.shutdown();
}
}

Semaphore(信号量)

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 ThreadStaggerBySemaphore {
private int num = 1;
private int maxNum = 40;

private void print(Semaphore curr, Semaphore next) {
while (num < maxNum) {
try {
curr.acquire();

System.out.println(Thread.currentThread().getName() + "-" + (num++));

next.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
final ExecutorService threadPool = Executors.newFixedThreadPool(2);
final Semaphore semaphore1 = new Semaphore(1);
final Semaphore semaphore2 = new Semaphore(0);

ThreadStaggerBySemaphore stagger = new ThreadStaggerBySemaphore();
threadPool.submit(() -> stagger.print(semaphore1, semaphore2));
threadPool.submit(() -> stagger.print(semaphore2, semaphore1));

threadPool.shutdown();
}
}

CyclicBarrier(循环栅栏)

主要用于让一组线程互相等待,直到所有线程都达到了一个公共屏障点(Barrier Point),然后这些线程才继续执行。

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
31
32
33
34
35
36
37
38
public class ThreadStaggerByCyclicBarrier {
private static volatile int num = 0;
private static int maxNum = 40;
// 屏障的限制个数为2,传入一个参数n,那么需要有n个线程都执行await方法,才会进入下一轮
private static final CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
static volatile boolean flag = true;

public static void main(String[] args) {
new Thread(() -> {
do {
if (flag) {
System.out.println(Thread.currentThread().getName() + "-" + (++num));
}
flag = false;
try {
// 进入阻塞,直到线程B也执行await方法
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
} while (num < maxNum);
}).start();

new Thread(() -> {
do {
if (!flag) {
System.out.println(Thread.currentThread().getName() + "-" + (++num));
}
flag = true;
try {
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
} while (num < maxNum);
}).start();
}
}

Queue(阻塞队列)

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
31
32
public class ThreadStaggerByQueue {
private static volatile int num = 0;
private static final int maxNum = 40;

public void print(BlockingQueue<Integer> curr, BlockingQueue<Integer> next) {
do {
try {
curr.take();

System.out.println(Thread.currentThread().getName() + "-" + (++num));

next.add(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (num < maxNum);
}

public static void main(String[] args) {
final ExecutorService threadPool = Executors.newFixedThreadPool(3);
final BlockingQueue<Integer> q1 = new LinkedBlockingQueue<Integer>() {{
add(0); // 加个值
}};
final BlockingQueue<Integer> q2 = new LinkedBlockingQueue<>();

ThreadStaggerByQueue threadPrint2 = new ThreadStaggerByQueue();
threadPool.submit(() -> threadPrint2.print(q1, q2));
threadPool.submit(() -> threadPrint2.print(q2, q1));

threadPool.shutdown();
}
}

volatile 变量

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
31
32
33
34
35
/**
* <b> 多线程交替打印
* <p> volatile 修饰的变量,可以换成数字类型,支持更多线程。 boolean只能两个线程
*
* @Author He.hp
* @Email haeng2030@gmail.com
* @Date 2024/11/21 22:20
*/
public class VolatileStagger {
static volatile boolean flag = true;
private static int num = 0;

public static void main(String[] args) {
new Thread(() -> {
do {
if (flag) {
System.out.println(Thread.currentThread().getName() + "-" + (++num));
flag = false;
}
} while (num < 100);

}, "A").start();

new Thread(() -> {

for (; num < 100; ) {
if (!flag) {
System.out.println(Thread.currentThread().getName() + "-" + (++num));
flag = true;
}
}

}, "B").start();
}
}

AtomicBoolean(CAS)

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
31
32
33
34
35
/**
* <b> 多线程交替打印
* <p> 基于cas的原子类
*
* @Author He.hp
* @Email haeng2030@gmail.com
* @Date 2024/11/21 22:59
*/
public class AtomicStagger {
static volatile AtomicBoolean flag = new AtomicBoolean(true);
private static int num = 0;

public static void main(String[] args) {
new Thread(() -> {
do {
if (flag.get()) {
System.out.println(Thread.currentThread().getName() + "-" + (++num));
flag.set(false);
}
} while (num < 100);

}, "A").start();

new Thread(() -> {

for (; num < 100; ) {
if (!flag.get()) {
System.out.println(Thread.currentThread().getName() + "-" + (++num));
flag.set(true);
}
}

}, "B").start();
}
}

LockSupport(阻塞/释放)

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
31
32
33
34
35
36
/**
* <b>多线程交替打印
* <p> LockSupport.park() 和 LockSupport.unpark(t2)
*
* @Author He.hp
* @Email haeng2030@gmail.com
* @Date 2024/11/21 23:05
*/
public class LockSupportStagger {
private static int num = 0;
static Thread t1 = null;
static Thread t2 = null;

public static void main(String[] args) {
t1 = new Thread(() -> {
do {
// 获取不到就会阻塞在这里
LockSupport.park();
System.out.println(Thread.currentThread().getName() + "-" + (++num));
// 这个参数不写1也没事,因为我们tryRelease没用到
LockSupport.unpark(t2);
} while (num < 100);
}, "A");
t2 = new Thread(() -> {
do {
LockSupport.park();
System.out.println(Thread.currentThread().getName() + "-" + (++num));
LockSupport.unpark(t1);
} while (num < 100);
}, "B");

t1.start();
t2.start();
LockSupport.unpark(t1);
}
}