下面将展示多线程交替打印的统一写法(基于线程名的),分别有synchronized和ReentranLock两种,都是阻塞式写法,以后也可以写个线程通信的写法(感兴趣的话)
A、B、C三个线程循环打印A、B、C (10次)
import java.util.concurrent.locks.ReentrantLock;
public class PrintABC {
int times = 10;
String name = "A";
ReentrantLock lock = new ReentrantLock();
// ReentrantLock实现
// public void printABC(String s) {
// for (int i = 0; i < times;) {
// lock.lock();
// try {
// if (Thread.currentThread().getName().equals(name)) {
// System.out.print(s);
// i++;
// if (name.equals("A")) {
// name = "B";
// } else if (name.equals("B")) {
// name = "C";
// } else {
// name = "A";
// }
// }
// } finally {
// lock.unlock();
// }
// }
// }
// synchronized实现
public void printABC(String s) {
for (int i = 0; i < times;) {
synchronized (PrintABC.class) {
if (Thread.currentThread().getName().equals(name)) {
System.out.print(s);
i++;
if (name.equals("A")) {
name = "B";
} else if (name.equals("B")) {
name = "C";
} else {
name = "A";
}
}
}
}
}
public static void main(String[] args) {
PrintABC printABC = new PrintABC();
new Thread(() -> printABC.printABC("A"), "A").start();
new Thread(() -> printABC.printABC("B"), "B").start();
new Thread(() -> printABC.printABC("C"), "C").start();
}
}
AA、BB、CC三个线程交替打印AA五次、BB十次、CC十五次,共循环10次
import java.util.concurrent.locks.ReentrantLock;
public class PrintAABBCC {
int n = 10; // 每个线程各执行print多少次
String name = "AA";
ReentrantLock lock = new ReentrantLock();
private void print(String s, int times) {
for (int i = 0; i < n;) {
synchronized (PrintABC.class) {
if (Thread.currentThread().getName().equals(name)) {
for (int j = 0; j < times; j++) {
System.out.print(s);
}
i++;
System.out.println();
if (name.equals("AA")) name = "BB";
else if (name.equals("BB")) name = "CC";
else name = "AA";
}
}
}
}
// private void print(String s, int times) {
// for (int i = 0; i < n;) {
// lock.lock();
// try {
// if (Thread.currentThread().getName().equals(name)) {
// for (int j = 0; j < times; j++) {
// System.out.print(s);
// }
// i++;
// System.out.println();
// if (name.equals("AA")) name = "BB";
// else if (name.equals("BB")) name = "CC";
// else name = "AA";
// }
// } finally {
// lock.unlock();
// }
// }
// }
public static void main(String[] args) {
PrintAABBCC printAABBCC = new PrintAABBCC();
new Thread(() -> printAABBCC.print("AA", 5), "AA").start();
new Thread(() -> printAABBCC.print("BB", 10), "BB").start();
new Thread(() -> printAABBCC.print("CC", 15), "CC").start();
}
}
odd、even两个线程交替打印1~100
import java.util.concurrent.locks.ReentrantLock;
public class OddEvenPrint {
int num = 50;
int curNum = 1;
String name = "odd";
ReentrantLock lock = new ReentrantLock();
// private void printOddEven() {
// for (int i = 0; i < num;) {
// synchronized (OddEvenPrint.class) {
// if (Thread.currentThread().getName().equals(name)) {
// System.out.println("线程" + name + ": 打印了" + curNum);
// if (name.equals("odd")) {
// name = "even";
// } else {
// name = "odd";
// }
// curNum++;
// i++;
// }
// }
// }
// }
private void printOddEven() {
for (int i = 0; i < num;) {
lock.lock();
try {
if (Thread.currentThread().getName().equals(name)) {
System.out.println("线程" + name + ": 打印了" + curNum);
if (name.equals("odd")) {
name = "even";
} else {
name = "odd";
}
curNum++;
i++;
}
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
OddEvenPrint oddEvenPrint = new OddEvenPrint();
new Thread(() -> oddEvenPrint.printOddEven(), "odd").start();
new Thread(() -> oddEvenPrint.printOddEven(), "even").start();
}
}
Num、Letter两个线程交替打印数字和字母,结果为1A2B3C...
import java.util.concurrent.locks.ReentrantLock;
public class NumAlterLetterPrint {
int times = 26;
String name = "Num";
int num = 1;
char letter = 'A';
ReentrantLock lock = new ReentrantLock();
private void print() {
for (int i = 0; i < times;) {
synchronized (NumAlterLetterPrint.class) {
if (Thread.currentThread().getName().equals(name)) {
if (name.equals("Num")) {
System.out.print(num++);
name = "Letter";
} else {
System.out.print(letter++);
name = "Num";
}
i++;
}
}
}
}
// private void print() {
// for (int i = 0; i < times;) {
// lock.lock();
// try {
// if (Thread.currentThread().getName().equals(name)) {
// if (name.equals("Num")) {
// System.out.print(num++);
// name = "Letter";
// } else {
// System.out.print(letter++);
// name = "Num";
// }
// i++;
// }
// } finally {
// lock.unlock();
// }
// }
// }
public static void main(String[] args) {
NumAlterLetterPrint numAlterLetterPrint = new NumAlterLetterPrint();
new Thread(() -> numAlterLetterPrint.print(), "Num").start();
new Thread(() -> numAlterLetterPrint.print(), "Letter").start();
}
}
N个线程交替打印0~99(这个没用线程名作信号,毕竟麻烦)
import java.util.concurrent.locks.ReentrantLock;
public class NThreadPrint {
int curNum = 0; // 当前打印到那个数字了
int times = 10; // 每个线程要打印多少次
static int n = 10; // 线程的数量
ReentrantLock lock = new ReentrantLock();
public void print(int threadNum) {
for (int i = 0; i < times;) {
synchronized (NThreadPrint.class) {
if (curNum % n == threadNum) {
System.out.println("线程" + threadNum + ": 打印了" + curNum++);
i++;
}
}
}
}
// private void print(int threadNum) {
// for (int i = 0; i < times;) {
// lock.lock();
// try {
// if (curNum % n == threadNum) {
// System.out.println("线程" + threadNum + ": 打印了" + curNum++);
// i++;
// }
// } finally {
// lock.unlock();
// }
// }
// }
public static void main(String[] args) {
NThreadPrint nThreadPrint = new NThreadPrint();
for (int i = 0; i < n; i++) {
int finalI = i;
new Thread(() -> nThreadPrint.print(finalI)).start();
}
}
}