问题:Java两个线程,一个输出字母,另一个输出数字,如何能得到1A2B3C4D…(除文中提到的方法肯定还有其它方法)
方法一:LockSupport
public class TestThread {
private static char[] data1 = {'1','2','3','4','5','6','7'};
private static char[] data2 = {'a','b','c','d','e','f','g'};
private static Thread t1,t2;
public static void main(String[] args) {
t1 = new Thread(
()->{
for(char temp : data1){
System.out.println(temp);
LockSupport.unpark(t2);//唤醒t2
LockSupport.park();//挂起当前线程
}
}
);
t2 = new Thread(
()->{
for(char temp : data2){
LockSupport.unpark(t1);//唤醒t1
System.out.println(temp);
LockSupport.park()//挂起当前线程
}
}
);
t1.start();
t2.start();
}
}
方法二:volatile + 自旋等待
public class TestThread {
private static char[] data1 = {'1','2','3','4','5','6','7'};
private static char[] data2 = {'a','b','c','d','e','f','g'};
private static Thread t1,t2;
private static volatile int currentThreadId = 1;
public static void main(String[] args) {
t1 = new Thread(
()->{
for(char temp : data1){
while(currentThreadId != 1) {
//忙等待
}
System.out.println(temp);
currentThreadId = 2;
}
}
);
t2 = new Thread(
()->{
for(char temp : data2){
while(currentThreadId != 2){
//忙等待
}
System.out.println(temp);
currentThreadId = 1;
}
}
);
t1.start();
t2.start();
}
}
方法三:原子类型 + 自旋等待
public class TestThread {
private static char[] data1 = {'1','2','3','4','5','6','7'};
private static char[] data2 = {'a','b','c','d','e','f','g'};
private static Thread t1,t2;
private static AtomicInteger currentThreadId = new AtomicInteger(1);
public static void main(String[] args) {
t1 = new Thread(
()->{
for(char temp : data1){
while(currentThreadId.get() != 1) {
//忙等待
}
System.out.println(temp);
currentThreadId.set(2);
}
}
);
t2 = new Thread(
()->{
for(char temp : data2){
while(currentThreadId.get() != 2){
//忙等待
}
System.out.println(temp);
currentThreadId.set(1);
}
}
);
t1.start();
t2.start();
}
}
方法四:阻塞队列
public class TestThread {
private static char[] data1 = {'1','2','3','4','5','6','7'};
private static char[] data2 = {'a','b','c','d','e','f','g'};
private static Thread t1,t2;
static BlockingQueue<String> q1 = new ArrayBlockingQueue<>(1);
static BlockingQueue<String> q2 = new ArrayBlockingQueue<>(1);
public static void main(String[] args) {
t1 = new Thread(
()->{
for(char temp : data1){
System.out.println(temp);
try {
q1.put("t1打印成功");//t2线程满足执行条件
q2.take();//如果没内容就阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
);
t2 = new Thread(
()->{
for(char temp : data2){
try {
q1.take();//如果没内容就阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(temp);
try {
q2.put("t2打印成功");//t1线程满足执行条件
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
);
t1.start();
t2.start();
}
}
方法五:synchronized + wait()/notify()
注:可以使用CountDownLatch或者volatile修饰的变量等多种办法来保证t1先运行
public class TestThread {
private static char[] data1 = {'1','2','3','4','5','6','7'};
private static char[] data2 = {'a','b','c','d','e','f','g'};
private static Thread t1,t2;
private static Object lock = new Object();
public static void main(String[] args) {
t1 = new Thread(
()->{
synchronized (lock) {
for (char temp : data1) {
System.out.println(temp);
lock.notify();//随机唤醒一个在lock上等待的线程
try {
lock.wait();//使当前线程等待,并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notify();//必须有,否则程序无法停止
}
}
);
t2 = new Thread(
()->{
synchronized (lock) {
for(char temp : data2){
System.out.println(temp);
lock.notify();//随机唤醒一个在lock上等待的线程
try {
lock.wait();//使当前线程等待,并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notify();//必须有,否则程序无法停止
}
}
);
t1.start();
t2.start();
}
}
方法六:Lock + Condition
注:可以使用CountDownLatch或者volatile修饰的变量等多种办法来保证t1先运行
public class TestThread {
private static char[] data1 = {'1','2','3','4','5','6','7'};
private static char[] data2 = {'a','b','c','d','e','f','g'};
private static Thread t1,t2;
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
t1 = new Thread(
()->{
try{
lock.lock();
for (char temp : data1) {
System.out.println(temp);
condition2.signal();
condition1.await();
}
condition2.signal();//不加程序可能不会停止
}catch (Exception e){
}finally {
lock.unlock();
}
}
);
t2 = new Thread(
()->{
try{
lock.lock();
for (char temp : data2) {
System.out.println(temp);
condition1.signal();
condition2.await();
}
condition1.signal();//不加程序可能不会停止
}catch (Exception e){
}finally {
lock.unlock();
}
}
);
t1.start();
t2.start();
}
}
420



被折叠的 条评论
为什么被折叠?



