3个线程顺序打印ABC10次

今年,唯品会的一道笔试题是三个线程顺序打印ABC10次,当时写得很乱,也写错了,现在给出我的解决方法:
package deadLockThread;

public class PrintThread {
	private static boolean flga1 = true;
	private static boolean flga2 = false;
	private static boolean flga3 = false;

	public static void main(String[] args) {
		final PrintThread o = new PrintThread();
		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					while (true) {
						synchronized (o) {

							if (!flga1) {
								try {
									o.wait();
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}

							} else {
								System.out.println(Thread.currentThread()
										.getName());
								flga1 = false;
								flga2 = true;
								flga3 = false;
								o.notifyAll();
								break;
							}
						}
					}

				}

			}
		}, "A");

		Thread t2 = new Thread(new Runnable() {

			@Override
			public void run() {

				for (int i = 0; i < 10; i++) {
					while (true) {
						synchronized (o) {
							if (!flga2) {
								try {
									o.wait();
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}

							} else {
								System.out.println(Thread.currentThread()
										.getName());
								flga1 = false;
								flga2 = false;
								flga3 = true;
								o.notifyAll();
								break;
							}
						}

					}
				}

			}
		}, "B");

		Thread t3 = new Thread(new Runnable() {

			@Override
			public void run() {

				for (int i = 0; i < 10; i++) {

					while (true) {
						synchronized (o) {
							if (!flga3) {
								try {
									o.wait();
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}

							} else {
								System.out.println(Thread.currentThread()
										.getName());
								flga1 = true;
								flga2 = false;
								flga3 = false;
								o.notifyAll();
								break;
							}
						}

					}
				}

			}
		}, "C");

		t1.start();
		t2.start();
		t3.start();

	}

}

其实,原理很简单,用三个标志来判断哪个线程应该wait 。在三个线程里面写入同步代码块,只有取得上面 o对象的对象锁,才能执行,这样保证同一时间只有一个线程在打印。配合wait 和notifyAll 还有三个标志就可以按照顺序打印ABC。

这是网上其他版本,我觉得他比我的好很多,代码简洁而且还是共用一个类,这样再增加线程也容易改动,很巧妙的使用AtomicInteger类 ,AtomicInteger类线程安全,适合在高并发中当计数器.

package com.mythread.test;

import java.util.concurrent.atomic.AtomicInteger;

public class T {
	public static void main(String argv[]) {
		
		AtomicInteger synObj = new AtomicInteger(0);
		
		TestPrint a = new TestPrint(synObj, "A", 0);
		TestPrint b = new TestPrint(synObj, "B", 1);
		TestPrint c = new TestPrint(synObj, "C", 2);
		
		a.start();
		b.start();
		c.start();
	}
}

class TestPrint extends Thread {
	
	private AtomicInteger synObj;
	private String name;
	private int flag;
	
	private int count = 0;
	
	public TestPrint(AtomicInteger synObj, String name, int flag) {
		this.synObj = synObj;
		this.name = name;
		this.flag = flag;
	}
	
	@Override
	public void run() {
		while (true) {
			synchronized (synObj) {
				if (synObj.get() % 3 == flag) {
					synObj.set(synObj.get() + 1);
					System.out.println(name);
					count++;
					synObj.notifyAll();
					if (count == 10) {
						break;
					}
				} else {
					try {
						synObj.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}


你可能感兴趣的:(java)