java实现线程间的通信

本文章旨在记录java线程之间通信的使用方法(学习为主),文中涉及的代码非原创。

来源:http://wingjay.com

如何让两个线程同时执行?

public class threadTest {

	public static void main(String[] args) {
		Thread A = new Thread(new Runnable() {

			@Override
			public void run() {
				printNumber("A");
			}
		});
		
		Thread B = new Thread(new Runnable() {
			
			@Override
			public void run() {
				printNumber("B");
			}
		});
		A.start();
		B.start();
	}

	public static void printNumber(String s) {
		int i = 0;
		while (i++ < 3) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(s + "===print:" + i);
		}
	}
}

多次输出结果(观察下面几张图的不同点与相同点):

             

我们可以看出,A、B线程是同时执行的。

如何等待一个线程执行完毕再执行另外一个?

public class threadTest {

	public static void main(String[] args) {
		Thread A = new Thread(new Runnable() {

			@Override
			public void run() {
				printNumber("A");
			}
		});
		
		Thread B = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("B开始等待A线程");
				try {
					A.join();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				printNumber("B");
			}
		});
		A.start();
		B.start();
	}

	public static void printNumber(String s) {
		int i = 0;
		while (i++ < 3) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(s + "===print:" + i);
		}
	}
}

输出结果:

观察结果,可以看到在B线程中先输出了一句“B开始等待A线程”,然后A线程开始执行,A线程执行完毕最后B线程开始执行,之所以会这样,因为我们加了这句代码,A.join();

join()方法的作用是使当前的线程停止下来,等待调用的线程执行完毕后再执行自身线程。(使得线程之间的并行操作暂时改变为串行操作)

如何让两个线程按照指定顺序交叉执行?

如果想要按照自己定义的顺序执行线程,依赖于join()是不行的,得需要更细粒度的去控制线程的执行顺序。

public class threadTest {

	public static void main(String[] args) {
		Object lock = new Object();
		Thread A = new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (lock) {
					System.out.println("A1");
					try {
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("A2");
					System.out.println("A3");
				}
				
			}
		});
		
		Thread B = new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized(lock) {
					System.out.println("B1");
					System.out.println("B2");
					System.out.println("B3");
					lock.notify();
				}
			}
		});
		
		A.start();
		B.start();
	}
}

输出结果:

解释下输出结果:

首先两个线程A、B共用一个对象锁,当A线程开始执行时将对象锁取走,此时B线程处于等待状态;A线程输出A1后调用方法wait(),使自身线程进入等待状态,释放对对象锁的持有权,此时B线程获得对象锁开始执行线程,分别输出B1、B2、B3,输出完毕后B线程调用notify()方法唤醒处于等待状态的A线程,A线程继续执行输出A2、A3。

如何使一个线程等待多个线程?

前面用到的join()方法可以使得当前线程等待其他线程,那如果需要等待多个线程该怎么办呢,我们可以用CountDownLatch。

public class threadTest {

	public static void main(String[] args) {
		int count = 3;
		CountDownLatch countDownLatch = new CountDownLatch(count);
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("当前线程为D线程,等待其他3个线程。");
				try {
					countDownLatch.await();
					System.out.println("其他3个线程已执行完毕,D线程开始...");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
		
		for(char threadName='A';threadName <='C';threadName++) {
			String name= String.valueOf(threadName);
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					System.out.println(name + "线程开始执行");
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(name + "线程执行完毕");
					countDownLatch.countDown();
				}
			}).start();
		}
	}
}

CountDownLatch相当于一个计数器,首先需要给他初始化一个计数值,当其他线程执行时我们可以递减这个计数值,当这个计数值减到0时,当前线程就可以继续执行了。

countDownLatch.await()   检查计数值是否为0,不为0时继续等待,为0时开始执行。

countDownLatch.countDown()    逐渐计数值,每次减。

CountDownLatch使用于一个线程等待多个线程的场景。

============================================

学习结束,以后继续学习线程相关知识。

猜你喜欢

转载自blog.csdn.net/jqc874789596/article/details/84748227