看到群里发了个面试题,实现两个线程交替打印从1到100,很基础,但是也很考验多线程的基本功,通用字段,注意volatile的使用,保证可见性


public static int i = 1;
public volatile static int j = 1;
public volatile static boolean flag = false;
public static int count = 0;

public static Lock lock = new ReentrantLock();
public static Condition conditionA = lock.newCondition();
public static Condition conditionB = lock.newCondition();

private static CountDownLatch latch = new CountDownLatch(2);
private static AtomicInteger numA = new AtomicInteger();
private static AtomicInteger numB = new AtomicInteger();

private static byte[] block = new byte[0];

利用 AtomicInteger 和 volatile

public static void test5() {

new Thread(() -> {
while (numA.get() < 10) {
if (!flag) {
System.out.println(Thread.currentThread().getName()
+ "----" + (numA.incrementAndGet()));
flag = true;
}

}
}).start();

new Thread(() -> {
while (numB.get() < 10) {
if (flag) {
System.out.println(Thread.currentThread().getName()
+ "----" + (numB.incrementAndGet()));
flag = false;
}

}
}).start();

}

使用信号去判断

public static void test1() {
new Thread(() -> {
while (i < 10) {
if (!flag) {
System.out.println(Thread.currentThread().getName()
+ "----" + (i++));
flag = true;
}
}
}).start();

new Thread(() -> {
while (j < 10) {
if (flag) {
System.out.println(Thread.currentThread().getName()
+ "----" + (-j++));
flag = false;
}
}
}).start();
}

使用 synchronized 和 wait notifyAll 来实现

public static void test6() {
new Thread(() -> {
while (i < 10) {
synchronized (block) {
if (flag) {
try {
block.wait();
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName()
+ "----" + (i++));
flag = true;
block.notifyAll();
}

}
}
}).start();

new Thread(() -> {
while (j < 10) {
synchronized (block) {

if (!flag) {
try {
block.wait();
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName()
+ "----" + (j++));
flag = false;
block.notifyAll();
}

}
}
}).start();
}


使用Lock 和 Condition 类实现,更加灵活一点

public static void test4() {

new Thread(() -> {
try {
lock.lock();
while (i < 10) {
if (flag) {
conditionA.await();
}
flag = true;
System.out.println(Thread.currentThread().getName() + "----"
+ (i++));
conditionB.signal();
}

} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} ).start();

new Thread(() -> {

try {
lock.lock();
while (j < 10) {
if (!flag) {
conditionB.await();
}
flag = false;
System.out.println(Thread.currentThread().getName() + "----"
+ (j++));
conditionA.signal();
}

} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} ).start();
}

使用Lock 实现

public static void test2() {
new Thread(() -> {
while (i < 10) {

try {
lock.lock();
while (!flag) {
System.out.println(Thread.currentThread().getName()
+ "----" + (i++));
flag = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();

new Thread(() -> {
while (j < 10) {

try {
lock.lock();
while (flag) {
System.out.println(Thread.currentThread().getName()
+ "----" + (j++));
flag = false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
}