java多线程交替打印两个数

方法1,使用wait和notify

package com.thread;

public class T01 {

	public static void main(String[] args) {
		char[] char1 = "AAAAAA".toCharArray();
		char[] char2 = "BBBBBB".toCharArray();
		Object object = new Object();
		
		Thread thread1 = new Thread(()  -> {
				synchronized(object){//使用notify和wait时,必须要选获取到锁
					for (int i = 0; i < char1.length; i++) {
						try {
							System.out.print(char1[i]);
							object.notify();
							object.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					object.notify();//必须加上,否则程序无法结束,两个线程总有一个最后是wait状态,所以此处必须加
			}
				
		},"t1");
		
		
		Thread thread2 = new Thread( () -> {
				synchronized(object){
					for (int i = 0; i < char2.length; i++) {
						try {
							System.out.print(char2[i]);
							object.notify();
							object.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					object.notify();
			}
		},"t2");
		
		thread1.start();
		thread2.start();
		
	}
}

方法2,使用LockSupport方法

package com.thread;

import java.util.concurrent.locks.LockSupport;

public class T02 {
	static Thread thread1 ;
	static Thread thread2 ;
	public static void main(String[] args) {
		char[] char1 = "AAAAAA".toCharArray();
		char[] char2 = "BBBBBB".toCharArray();
		
		thread1 = new Thread(() -> {
				for (int i = 0; i < char1.length; i++) {
					System.out.print(char1[i]);
					LockSupport.unpark(thread2);
					LockSupport.park();
				}
		},"t1");
		
		 thread2 = new Thread(() -> {
				for (int i = 0; i < char2.length; i++) {
					LockSupport.park();
					System.out.print(char2[i]);
					LockSupport.unpark(thread1);
				}
		},"t2");
		
		thread1.start();
		thread2.start();
		
	}
	
	
}

方法3,使用CAS自旋锁

package com.thread;

public class T03 {
	enum ReadEnum{
		T1,
		T2;
	}
	static volatile ReadEnum r  = ReadEnum.T1;
	public static void main(String[] args) {
		char[] char1 = "AAAAAA".toCharArray();
		char[] char2 = "BBBBBB".toCharArray();
		Thread thread1 = new Thread(() ->{
			for (int i = 0; i < char1.length; i++) {
				while (r != ReadEnum.T1) {
				}
				System.out.print(char1[i]);
				r = ReadEnum.T2;
			}
		},"t1");
		
		
		Thread thread2 = new Thread(() ->{
			for (int i = 0; i < char2.length; i++) {
				while (r != ReadEnum.T2) {
				}
				System.out.print(char2[i]);
				r = ReadEnum.T1;
			}
		},"t2");
		
		thread1.start();
		thread2.start();
		
		
	}
}

方法4,使用Condition方法

package com.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;


public class T04 {

	public static void main(String[] args) {
		char[] char1 = "AAAAAA".toCharArray();
		char[] char2 = "BBBBBB".toCharArray();
		
		ReentrantLock lock = new ReentrantLock();
		Condition condition1 = lock.newCondition();
		Condition condition2 = lock.newCondition();
		
		Thread thread1 = new Thread(() ->{
			try {
				lock.lock();
				for (int i = 0; i < char1.length; i++) {
					System.out.print(char1[i]);
					condition2.signal();//唤醒线程2执行
					condition1.await();//线程1等待
				}
				condition2.signal();
			}catch (Exception e) {
				e.printStackTrace();
			}finally{
				lock.unlock();
			}
		},"t1");
		
		Thread thread2 = new Thread(() ->{
			try {
				lock.lock();
				for (int i = 0; i < char2.length; i++) {
					System.out.print(char2[i]);
					condition1.signal();
					condition2.await();
				}
				condition1.signal();
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				lock.unlock();
			}

		},"t2");
		
		thread1.start();
		thread2.start();
		
		
	}
}

打印结果:


Condition与notify相比的好处是,Condition可以指定需要唤醒的线程,而notify是无法指定的,只能随机唤醒一个或者全唤醒(notifyAll)

你可能感兴趣的:(java)