看到群里发了个面试题,实现两个线程交替打印从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();
}