使用Condition + Lock 进行实现
private static int count_print = 1;
(1)此处只能用static,来实现每打印一个字符,下一个字符长度加一,static是使该变量只有一个副本,任何改变都是对这个副本的内容做操作
(2)若是想实现每打印一组,下一组字符每个字符长度加一,就不使用static,线程没有执行完,不会立刻写入主存,其他线程就不可见
(3)如果使用volatile,volatile是当前线程执行完毕后才会强制将该变量写入主存,让所有线程可见,所以volatile不是线程安全的
程序一:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest implements Runnable {
public static final int COUNT = 5;
private final ReentrantLock reentrantLock;
private final Condition thisCondition;
private final Condition nextCondition;
private final char printChar;
//此处只能用static,来实现每打印一个字符,下一个字符长度加一,static是使该变量只有一个副本,任何改变都是对这个副本的内容做操作
//若是想实现每打印一组,下一组字符每个字符长度加一,就不使用static,线程没有执行完,不会立刻写入主存
//如果使用volatile,volatile是当前线程执行完毕后才会强制将该变量写入主存,让所有线程可见,所以volatile不是线程安全的
private static int count_print = 1;
public ThreadTest(ReentrantLock reentrantLock, Condition thisCondition, Condition nextCondition, char printChar) {
this.reentrantLock = reentrantLock;
this.thisCondition = thisCondition;
this.nextCondition = nextCondition;
this.printChar = printChar;
}
@Override
public void run() {
reentrantLock.lock();
try {
for (int i = 0; i < COUNT; i++) {
for (int j = 0; j < count_print; j++) {
System.out.print(printChar);
}
count_print += 1;
nextCondition.signal();
// 不是最后一次则通过thisCondtion等待被唤醒
// 必须要加判断,不然虽然能够打印5次,但5次后就会直接死锁
if (i < COUNT - 1) {
try {
//使用Condition的await()方法将当前线程放入等待队列,并使其能在下一次被唤醒继续往下执行,而不是从头开始执行
thisCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} finally {
reentrantLock.unlock();
}
}
public static void main(String args[]) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
Thread threadA = new Thread(new ThreadTest(lock, conditionA, conditionB, 'A'));
Thread threadB = new Thread(new ThreadTest(lock, conditionB, conditionC, 'B'));
Thread threadC = new Thread(new ThreadTest(lock, conditionC, conditionA, 'C'));
threadA.start();
Thread.sleep(100);
threadB.start();
Thread.sleep(100);
threadC.start();
}
}
(1)//此处只能用static,来实现每打印一个字符,下一个字符长度加一,static是使该变量只有一个副本,任何改变都是对这个副本的内容做操作
private static int count_print = 1;
输出结果:
(2)若是想实现每打印一组,下一组字符每个字符长度加一,就不使用static,线程没有执行完,不会立刻写入主存
private int count_print = 1;
输出结果:
(3)如果使用volatile,volatile是当前线程执行完毕后才会强制将该变量写入主存,让所有线程可见,所以volatile不是线程安全的
private volatile int count_print = 1;
输出结果:同上
程序二
//只是循环打印每组字符,不考虑字符增长
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest implements Runnable {
public static final int COUNT = 5;
private final ReentrantLock reentrantLock;
private final Condition thisCondition;
private final Condition nextCondition;
private final char printChar;
//此处只能用static,来实现每打印一个字符,下一个字符长度加一,static是使该变量只有一个副本,任何改变都是对这个副本的内容做操作
//若是想实现每打印一组,下一组字符每个字符长度加一,就不使用static,线程没有执行完,不会立刻写入主存
//如果使用volatile,volatile是当前线程执行完毕后才会强制将该变量写入主存,让所有线程可见,所以volatile不是线程安全的
private static int count_print = 1;
public ThreadTest(ReentrantLock reentrantLock, Condition thisCondition, Condition nextCondition, char printChar) {
this.reentrantLock = reentrantLock;
this.thisCondition = thisCondition;
this.nextCondition = nextCondition;
this.printChar = printChar;
}
@Override
public void run() {
reentrantLock.lock();
try {
for (int i = 0; i < COUNT; i++) {
System.out.print(printChar);
nextCondition.signal();
if (i < COUNT - 1) {
try {
//使用Condition的await()方法将当前线程放入等待队列,并使其能在下一次被唤醒继续往下执行,而不是从头开始执行
thisCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} finally {
reentrantLock.unlock();
}
}
public static void main(String args[]) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
Thread threadA = new Thread(new ThreadTest(lock, conditionA, conditionB, 'A'));
Thread threadB = new Thread(new ThreadTest(lock, conditionB, conditionC, 'B'));
Thread threadC = new Thread(new ThreadTest(lock, conditionC, conditionA, 'C'));
threadA.start();
Thread.sleep(100);
threadB.start();
Thread.sleep(100);
threadC.start();
}
}
运行结果为: