常见面试题
面试官一般都会问线程都有哪几种创建方式?
应聘者一般都会回调3或者四种。实际上,真正的线程创建方式只有2种。
继承thread类 和 实现runnable接口有什么区别?
实现runnable接口,只是创建任务,可以给多个线程使用,相对来说更加灵活。
run和start方法的区别?
run相当于普通方法直接调用,而start方法才是真正的开启一个线程并执行。
多线程一定比串行执行快吗?
不一定。多线程只有在代码中存在io或者网络传输的情况下才会比串行快。因为io或者网络传输的情况下,此时cpu空间,多线程利用到了cpu的时间片才会使得程序更快响应。而不存在上述的情况下,只会增加线程上下文频繁切换,造成资源的浪费。
yiled,sleep,wait的区别?
sleep是抱着锁睡觉,属于TIME_WAITTING。
怎么停止正在运行的线程?
- 使用标记位(jdk推荐使用这种方式)
- 使用thread.stop()方法。(该方法已过时,因为使用stop方法,会使得当前线程释放掉已获取到的锁,会导致对象状态不一致的问题,因为锁可以保证操作的原子性。)
- 使用thread.interrupt方法。(interrupt方法有很多限制,需要线程自己打断,并且这时候线程不能等待或者阻塞,否则都会抛出异常。)
线程的状态
New
新生状态,还没有调用start方法
RUNNABLE
运行状态,java线程中有就绪和运行俩个状态,就绪状态就是还没有时间片分配。
BLOCKED
阻塞状态,表示线程阻塞与于锁,也就是存在于多线程访问同步代码块。
WAITTING
等待状态,需要其他线程唤醒或者中断。比如wait操作。
TIME_WAITTING
超时等待状态,有时间的等待。sleep操作。
TERMINATED
终止状态,表示当前线程已经执行完毕。
线程的分类
用户线程
用户线程就是相当于前台线程,jvm需要等待前台线程执行完毕才能停止。
守护线程
守护线程相当于后台线程,jvm不需要等待前台线程执行完毕就可以停止。可以通过下面这种方式来设置。
thread.setDaemon(true);
线程的创建方式
继承thread类
class MyThread extends Thread{@Overridepublic void run() {System.out.println("MyThread1.run");}}
实现runnable接口
class MyThread implements Runnable{@Overridepublic void run() {System.out.println("MyThread.run");}}
实现callable接口
class Task implements Callable<Integer>{@Overridepublic Integer call() throws Exception {return 1;}}public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(1);Future<Integer> future = executorService.submit(task);System.out.println(future.get());}
通过线程池来创建
public static void main(String[] args) throws ExecutionException, InterruptedException {ThreadFactory threadFactory = new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {return new Thread(r);}};Thread thread = threadFactory.newThread(new Runnable() {@Overridepublic void run() {System.out.println("JdbcMain.run");}});thread.start();System.out.println("JdbcMain.main");}
