都是接口。
Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;
Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。
volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。
但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。
synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞。 volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。 volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。
synchronized 保证三大性,原子性,有序性,可见性,
volatile 保证有序性,可见性,不能保证原子性。
sleep方法和wait方法都可以用来放弃CPU一定的时间暂停当前运行的线程,不同点在于如果线程持有某个对象的监锁,sleep方法不会释放这个对象的锁,wait方法会释放这个对象的锁,sleep必须要设定时间,而wait可以设定也可以不设定。
Sleep属于Thread类,wait属于Object类。
多线程的上下文切换是指CPU控制权由一个已经正在运行的线程切换到另外一个就绪并等待获取CPU执行权的线程的过程。
如果使用的LinkedBlockingQueue,也就是无界队列的话,继续添加任务到阻塞队列中等待执行,因为LinkedBlockingQueue可以无限存放任务;如果使用的是有界队列比方说ArrayBlockingQueue的话,则会使用拒绝策略RejectedExecutionHandler处理满了的任务。
线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。它是一种特殊的线程绑定机制,将变量与线程 绑定 在一起,为每一个线程维护一个独立的变量副本。Java 提供 ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。
ThreadLocal 无法解决共享对象的更新问题, ThreadLocal 对象建议使用 static修饰。这个变量是针对一个线程内所有操作共有的,所以设置为静态变量,所有此类实例共享此静态变量 ,也就是说在类第一次被使用时装载,只分配一块存储空间,所有此类的对象 ( 只要是这个线程内定义的 ) 都可以操控这个变量。
两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象。
以上这几个问题,如果你不是很清楚,建议复习一遍多线程的知识,多线程是面试必问的内容,也是一个复杂的知识点,在学习Java的过程中是一定要搞明白的,可以参考我的专栏,一共分为15篇文章:
同:
异:
线程调度器选择优先级最高的线程运行,但是,如果发生以下情况,就会终止线程的运行:
(1)线程体中调用了 yield 方法让出了对 cpu 的占用权利
(2)线程体中调用了 sleep 方法使线程进入睡眠状态
(3)线程由于 IO 操作受到阻塞
(4)另外一个更高优先级线程出现
(5)在支持时间片的系统中,该线程的时间片用完