接着上一篇内容,这次面试主要围绕多线程进行提问。接下来让我编程:串行执行三个线程,任务是每一个线程将i加1。我当时使用的是join()方法,但是由于对join()方法理解的不透彻。对自己的代码信心不大。我在这再写一遍:
public class SerialDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("main thread start");
SerialThread serialThread_1 = new SerialThread("thread_1");
SerialThread serialThread_2 = new SerialThread("thread_2");
SerialThread serialThread_3 = new SerialThread("thread_3");
serialThread_1.start();
serialThread_1.join();
serialThread_2.start();
serialThread_2.join();
serialThread_3.start();
serialThread_3.join();
System.out.println("main thread end");
}
}
class SerialThread extends Thread{
private String name;
public SerialThread(String name){
this.name = name;
}
static int i=0;
@Override
public void run() {
System.out.println("SerialThread run start name:"+name+",i="+i);
i++;
System.out.println("SerialThread run end"+name+",i="+i);
}
}
结果:
main thread start
SerialThread run start name:thread_1,i=0
SerialThread run endthread_1,i=1
SerialThread run start name:thread_2,i=1
SerialThread run endthread_2,i=2
SerialThread run start name:thread_3,i=2
SerialThread run endthread_3,i=3
main thread end
thread.join()方法的意义是抢占当前线程的执行时间切片,也就是说阻塞当前线程,运行thread,当thread运行结束后,再运行当前线程。以实现线程的串行执行。在上述代码中,首先运行主线程,接着运行thread_1.start()运行线程1,随后调用thread_1.join()。阻塞主线程,那主线程中的下一句thread_2.start()就不会执行,直到thread_1执行完毕。主线程继续运行调用thread_2.start(),实现线程的串行。其实,这不是完全意义的thread_1 thread_2 thread_3串行执行,而是thread_1执行完回到主线程,接着执行thread_2。也就是说串行执行是由主线程控制并调度。我想这不是面试官考我的真实考点。于是,下面一种解决方案:
public class SerialThreadDemo_2 {
static int i=0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
add();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
//引用t1线程,等待t1线程执行完
t1.start();
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
add();
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
//引用t2线程,等待t2线程执行完,一定要在此处t2.start()
//在主线程中调用t2.start()执行顺序不确定,因为若t2.join()先于t2.start()运行
//导致结果不确定
t2.start();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
add();
}
});
t3.start();
// t2.start();
// t1.start();
}
public static void add(){
System.out.println("add start in thread name:"+Thread.currentThread().getName()+",i:"+i);
i++;
System.out.println("add end in thread name:"+Thread.currentThread().getName()+"i,:"+i);
}
}
费了些力气才写了出来,说明自己水平还是欠修炼
结果:
add start in thread name:Thread-0,i:0
add end in thread name:Thread-0,i:1
add start in thread name:Thread-1,i:1
add end in thread name:Thread-1,i:2
add start in thread name:Thread-2,i:2
add end in thread name:Thread-2,i:3