最近在看面试题,看到了一个问题,这里记一下想出来的解决方法:
问题:
利用多线程打印:A12B23C34D45E56F67G78H89I910J1011K1112L1213M1314N1415O1516P1617Q1718R1819S1920T2021U2122V2223W2324X2425Y2526Z
想了一下,决定用Lock来实现,下面是实现方法:
先导包:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
将需要的方法放在一个类里,方便加锁:
public class MyService {
private ReentrantLock lock=new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean flag=false;
int i=0;
String[] str= {"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 set() {
try {
for (; i < str.length;) {
lock.lock();
if(flag==true) {
condition.await();
}
System.out.print(str[i]);
flag=true;
i++;
condition.signal();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void get() {
try {
for (; i < str.length;) {
lock.lock();
if(flag==false ) {
condition.await();
}
System.out.print(i);
System.out.print(i+1);
flag=false;
condition.signal();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
再写两个多线程类:
public class MyThreadA extends Thread{
private MyService service;
public MyThreadA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.set();
}
}
public class MyThreadB extends Thread{
private MyService service;
public MyThreadB(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.get();
}
}
然后测试:
public static void main(String[] args) {
MyService myService = new MyService();
MyThreadA a = new MyThreadA(myService);
MyThreadB b = new MyThreadB(myService);
a.start();
b.start();
}
最终结果:
另外还可以使用CyclicBarrier也可以有这种效果(底层也是使用Lock):
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
代码
public class CyclicTest {
String[] str= {"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"};
CyclicBarrier ccb=new CyclicBarrier(1, new myAction());
int i=0;
class myAction implements Runnable{
@Override
public void run() {
if(i<=str.length-1) {
System.out.print(i);
System.out.print(i+1);
}
}
}
}
class ThreadA implements Runnable {
private CyclicTest cct;
public ThreadA(CyclicTest cct) {
super();
this.cct = cct;
}
@Override
public void run() {
for (; cct.i < cct.str.length;) {
try {
System.out.print(cct.str[cct.i]);
cct.i++;
cct.ccb.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
最后测试方法:
public static void main(String[] args) {
CyclicTest cct =new CyclicTest();
new Thread(new ThreadA(cct)).start();
}