1、线程睡眠法
启动三条线程,每条线程睡眠指定的时间,从而达到效果。
private static void sleep() {
System.out.println("========enter sleep========");
ThreadFactory factory = ThreadFactoryBuilder.getThreadFactory("priority");
ExecutorService es = new ThreadPoolExecutor(3, 6, 10, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(20), factory, new ThreadPoolExecutor.AbortPolicy());
es.execute(new SleepThread(1, "A"));
es.execute(new SleepThread(4, "B"));
es.execute(new SleepThread(7, "C"));
es.shutdown();
System.out.println("========sleep end========");
}
private static class SleepThread extends Thread {
private int sleepSecond = 0;
public SleepThread(int sleepSecond, String name) {
setName(name);
this.sleepSecond = sleepSecond;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(sleepSecond);
System.out.println("Hello World!!!" + getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2、线程的join方法
注:不能使用线程池来启动线程,必须自己调用start方法才有效
private static void joinMethod() {
Thread a = new JoinThread(null, "A");
Thread b = new JoinThread(a, "B");
Thread c = new JoinThread(b, "C");
a.start();
b.start();
c.start();
}
private static class JoinThread extends Thread {
private Thread prev;
public JoinThread(Thread prev, String name) {
this.prev = prev;
setName(name);
}
@Override
public void run() {
try {
if(prev != null) {
System.out.println("before prev join " + getName());
prev.join();
}
System.out.println("Hello World!!! " + getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3、基于共享对象加锁的方法
private static void shareVariables() {
Share share = new Share();
ThreadFactory factory = ThreadFactoryBuilder.getThreadFactory("priority");
ExecutorService es = new ThreadPoolExecutor(3, 6, 10, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(20), factory, new ThreadPoolExecutor.AbortPolicy());
es.execute(new ShareVariablesThread(1, "A", share));
es.execute(new ShareVariablesThread(2, "B", share));
es.execute(new ShareVariablesThread(3, "C", share));
es.shutdown();
}
private static class ShareVariablesThread extends Thread {
private int num;
private Share share;
public ShareVariablesThread(int num, String name, Share share) {
this.num = num;
this.share = share;
setName(name);
}
@Override
public void run() {
try {
share.print(num, getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class Share {
private static volatile int num = 1;
/**
* 将下面的内置锁替换为Lock显示锁也可
*/
public synchronized void print(int threadNum, String threadName) throws InterruptedException{
while(num != threadNum) {
//wait会释放锁
wait();
}
System.out.println("Hello World!!! " + threadName);
num++;
notifyAll();
}
}
4、基于CoundDownLatch的使用
注:这种方法操作比较重,不推荐
private static void countDownLatch() {
ThreadFactory factory = ThreadFactoryBuilder.getThreadFactory("priority");
ExecutorService es = new ThreadPoolExecutor(3, 6, 10, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(20), factory, new ThreadPoolExecutor.AbortPolicy());
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch nextLatch = new CountDownLatch(1);
es.execute(new CountDownLatchThread(null, latch, "A"));
es.execute(new CountDownLatchThread(latch, nextLatch, "B"));
es.execute(new CountDownLatchThread(nextLatch, null, "C"));
es.shutdown();
}
private static class CountDownLatchThread extends Thread {
private CountDownLatch latch;
private CountDownLatch nextLatch;
private CountDownLatchThread(CountDownLatch latch, CountDownLatch nextLatch, String name) {
this.latch = latch;
this.nextLatch = nextLatch;
setName(name);
}
@Override
public void run() {
try {
if(latch != null) {
latch.await();
}
System.out.println("Hello World!!! " + getName());
if(nextLatch != null) {
nextLatch.countDown();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
5、基于优先级队列的方式
private static void priority() {
System.out.println("========enter priority========");
ThreadFactory factory = ThreadFactoryBuilder.getThreadFactory("priority");
ExecutorService es = new ThreadPoolExecutor(0, 1, 10, TimeUnit.SECONDS,
new PriorityBlockingQueue<>(3), factory, new ThreadPoolExecutor.AbortPolicy());
es.execute(new PriorityThread(1, "A"));
es.execute(new PriorityThread(2, "B"));
es.execute(new PriorityThread(3, "C"));
es.shutdown();
System.out.println("========priority end========");
}
private static class PriorityThread extends Thread implements Comparable<PriorityThread> {
private int printPriority = 0;
public int getPrintPriority() {
return printPriority;
}
public void setPrintPriority(int printPriority) {
this.printPriority = printPriority;
}
public PriorityThread(int priority, String name) {
setName(name);
this.printPriority = priority;
}
@Override
public void run() {
System.out.println("Hello World!!! " + getName());
}
@Override
public int compareTo(@NonNull PriorityThread o2) {
return Integer.compare(this.printPriority, o2.printPriority);
}
}
总结:
首先第5种方式并不是同时启动了3条线程,只有1条线程,然后根据优先级设置先执行优先级高的任务(Runnable)。
然后第一种线程睡眠法虽然能达到效果,但我认为不是此题的正确解法。
第二种join方法,不能使用线程池来进行创建,这是一个很严重的缺点。
第4种方式如注解说的一致, 该题的本意应该是考线程的阻塞(个人理解)
最后, 如果你有其他方法也能达到同样的效果,欢迎在下面留言!