网上看到了一个题目:
输入N个线程,然后顺序打印数字从0到100,输出结果类似如下:
thread0 value is0
thread1 value is1
thread2 value is2
thread3 value is3
thread0 value is4
思路是解决线程的序号,定义一个atomic的原子integer,初始值为0,然后判断序号是否等于当前integer的值,或者integer整除N是否等于当前序号,如果等于,则打印,并将原子integer 自增,然后唤醒其他的线程,否则的话就等待。
只测试了部分值,发现没有问题。
代码如下:
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
//通过N个线程顺序循环打印从0至100
public class ThreadDemo implements Runnable {
private static int totalNumber = 100;
private static AtomicInteger value = new AtomicInteger(0);
private static int inputNum = 0;
private static CountDownLatch countDownLatch;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int threadNum = in.nextInt();
inputNum = threadNum;
countDownLatch = new CountDownLatch(threadNum);
for (int i = 0; i < threadNum; i++) {
new Thread(new ThreadDemo(), "thread" + i).start();
countDownLatch.countDown();
}
}
@Override
public void run() {
try {
countDownLatch.await();
//System.out.println("begin value is " + value.get());
while (value.get() < totalNumber) {
synchronized (value) {
String name = Thread.currentThread().getName();
int taskThreadNum = Integer.parseInt(name.substring(6, 7));
if (value.get() == taskThreadNum || value.get() % inputNum == taskThreadNum) {
System.out.println(name + " value is" + value);
value.getAndIncrement();
value.notifyAll();
} else {
value.wait();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
华为Java高级面试题:用两个线程,一个输出字母,一个输出数字,交替输出1A2B3C4D...26Z
代码如下 :
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author: yancun
* @create: 2020/4/12
* @description:
*/
public class ThreadDemo {
private AtomicBoolean flag = new AtomicBoolean(true);
public static void main(String[] args) throws Exception{
ThreadDemo demo = new ThreadDemo();
new Thread(demo.new ThreadOne(),"线程1").start();
new Thread(demo.new ThreadTwo(),"线程2").start();
Thread.sleep(200);
System.out.println("结束");
}
class ThreadOne implements Runnable {
public void run() {
int i = 1;
while( i < 27) {
synchronized (flag) {
if (flag.get()) {
System.out.print(i);
i++;
flag.set(false);
flag.notifyAll();
} else {
try {
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class ThreadTwo implements Runnable {
private String[] charArray = new String[]{"A","B","C","D"
,"E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T"
,"U","V","W","X","Y","Z"};
public void run() {
int i = 0;
while( i < 26) {
synchronized (flag) {
if (!flag.get()) {
System.out.print(charArray[i]);
if (i == 25) {
System.out.println();
}
i++;
flag.set(true);
flag.notifyAll();
} else {
try {
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
使用lock 实现
其实跟上面是一样 就是将synchronized 替换为lock
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author: yancun
* @create: 2020/4/13 21:42
* @description:
*/
public class ThreadLockDemo {
private AtomicBoolean flag = new AtomicBoolean(true);
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public static void main(String[] args) throws Exception {
ThreadLockDemo demo = new ThreadLockDemo();
new Thread(demo.new ThreadOne(), "线程1").start();
new Thread(demo.new ThreadTwo(), "线程2").start();
Thread.sleep(200);
System.out.println("结束");
}
class ThreadOne implements Runnable {
public void run() {
int i = 1;
while (i < 27) {
lock.lock();
if (flag.get()) {
System.out.print(i);
i++;
flag.set(false);
condition.signalAll();
lock.unlock();
} else {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
class ThreadTwo implements Runnable {
private String[] charArray = new String[]{"A", "B", "C", "D"
, "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T"
, "U", "V", "W", "X", "Y", "Z"};
public void run() {
int i = 0;
while (i < 26) {
lock.lock();
if (!flag.get()) {
System.out.print(charArray[i]);
if (i == 25) {
System.out.println();
}
i++;
flag.set(true);
condition.signalAll();
lock.unlock();
} else {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
}