问一个Java多线程的问题

给定两个class:

public class Solution {
    public static final int THREAD_COUNT = 2;

    public static void main(String[] args) throws InterruptedException {

        Thread[] pool = new Thread[THREAD_COUNT];
        for (int i = 0; i < THREAD_COUNT; i++) {
            pool[i] = new Thread(new Printer(i));
            pool[i].start();
        }

        for (int i = 0; i < THREAD_COUNT; i++) {
            pool[i].join();
        }
        System.out.println("Job is done");
    }
}

public class Printer implements Runnable {

    public static final int ROUND = 10;
    private int id = 0;

    public Printer(int i) {
        this.id = i;
    }

    @Override
    public void run() {
        for (int i = 0; i < ROUND; i++) {
            System.out.print('A');
            System.out.print('B');
        }

    }
}

运行结果是:ABABABABAABABABABABABABABABABABBABABABAB
A和B是随机出现的。

要求:修改Printer.java,打印出以下结果:
AABBAABBAABBAABBAABBAABBAABBAABBAABBAABB
每个线程顺序打印A和B

这是苹果的经典题

啊?!

你说下是啥公司, 我贴给你答案
两种解法

  1. 简单方法:lock with busy waiting
  2. 复杂方法:blocking queue for notification

这是我写的:

public class Printer implements Runnable {

    public static final int ROUND = 20;
    private int id = 0;
    private final AtomicBoolean flag;
    private final AtomicInteger count;

    public Printer(int i, AtomicBoolean f, AtomicInteger c) {
        this.id = i;
        this.flag = f;
        this.count = c;
    }

    @Override
    public void run() {

        synchronized (flag) {
            for (int i = 0; i < ROUND; i++) {
                if (flag.get()) {
                    System.out.print('A');
                    if (count.get() == THREAD_COUNT) {
                        count.set(1);
                        flag.set(false);
                    } else {
                        count.incrementAndGet();
                    }
                } else {
                    System.out.print('B');
                    if (count.get() == THREAD_COUNT) {
                        count.set(1);
                        flag.set(true);
                    } else {
                        count.incrementAndGet();
                    }
                }
                flag.notify();
                try {
                    flag.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            flag.notify();
        }
    }
}
public class Solution {
    public static final int THREAD_COUNT = 2;

    public static void main(String[] args) throws InterruptedException {

        Thread[] pool = new Thread[THREAD_COUNT];
        AtomicBoolean flag = new AtomicBoolean(true);
        AtomicInteger counter = new AtomicInteger(1);

        for (int i = 0; i < THREAD_COUNT; i++) {
            pool[i] = new Thread(new Printer(i, flag, counter));
            pool[i].start();
        }

        for (int i = 0; i < THREAD_COUNT; i++) {
            pool[i].join();
        }
        System.out.println("Job is done");
    }
}

当THREAD_COUNT = 3时会发生死锁,THREAD_COUNT = 4也死锁,搞不懂为啥

你说下是啥公司

别人问我的,我以为是他的作业

那我只写个1了
2就不写了
2是可以用 BlockingQueuetake 方法


public class Solution {
	public static final int THREAD_COUNT = 2;

	public static void main(String[] args) throws InterruptedException {
		runPrintersBusyWaiting();
	}

	private static void runPrintersBusyWaiting() throws InterruptedException {
		Thread[] pool = new Thread[THREAD_COUNT];
		AtomicInteger counter = new AtomicInteger(0);
		for (int i = 0; i < THREAD_COUNT; i++) {
			pool[i] = new Thread(new PrinterBusyWaiting(i, counter, THREAD_COUNT));
			pool[i].start();
		}

		for (int i = 0; i < THREAD_COUNT; i++) {
			pool[i].join();
		}
		System.out.println("\nJob is done");
	}
}

class PrinterBusyWaiting implements Runnable {

	public static final int ROUND = 10;
	private int id = 0;
	private final AtomicInteger counter;
	private final int n;

	public PrinterBusyWaiting(int i, AtomicInteger counter, int n) {
		this.id = i;
		this.counter = counter;
		this.n = n;
	}

	@Override
	public void run() {
		for (int i = 0; i < ROUND; i++) {
			while (this.counter.get() % (2 * n) != id) {
			}
			System.out.print('A');
			this.counter.getAndIncrement();
			while (this.counter.get() % (2 * n) != id + n) {
			}
			System.out.print('B');
			this.counter.getAndIncrement();
		}

	}
}

竟然能这么干!!

你多线程还需要加强啊
我面苹果是三分钟写了两种解法

牛!