使用多线程循环交替打印字符

使用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();
}
}

扫描二维码关注公众号,回复: 1580582 查看本文章

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();
}
}

 运行结果为:

猜你喜欢

转载自www.cnblogs.com/windy-xmwh/p/9176553.html