十一、start()和run()的区别
start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。
这是Thread 类里面的run()方法public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }
@Override public void run() { if (target != null) { target.run(); } }
十二、sleep()函数与wait()函数的区别
注意:传递给线程Thread.sleep(long) 调用的毫秒数只是一个提示调度器当前线程有多长时间不需要被执行。实际运行中,调度器有可能几毫秒之前或之后让线程再执行。因此,Thread.sleep() 不能用于实时处理。
1、sleep()函数是Thread类的静态方法
public static native void sleep(long millis) throws InterruptedException;
2、wait()是object类的方法
public final void wait() throws InterruptedException { wait(0); }
3、sleep()方法没有释放锁,而wait()方法释放了锁,使得其他线程可以使用同步控制块或者方法.
4、wait()函数只能在同步代码块中调用
十三、notify()与notifyAll()函数的区别
notify()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用武之地。
而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。
十四、interrupted()函数与isInterrupted()函数的区别
interrupted()是Thread类的静态方法,用于检查当前执行的线程是否被中断,中断状态会被清零。
public static boolean interrupted() { return currentThread().isInterrupted(true); }
非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。
public boolean isInterrupted() { return isInterrupted(false); }
十五、submit()与execute()方法的区别
两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中。
而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中。
十六、Runnable和Callable接口区别
Runnable的run()方法没有返回值
Callable的call()方法有返回值,可以抛出异常,返回Future对象
十七、CyclicBarrier 和CountDownLatch区别
相同点:都可以等待其他并发任务的完成,在某个时间点上进行同步
cyclicBarrier可以被重置到初始状态,并把内部的计数器重置成初始化的值 对应的函数 reset()
CountDownLatch不能被重用
十八、RecursiveTask和RecursiveAction之间的区别
RecursiveAction的compute()方法没有返回值
RecursiveTask的compute()方法有返回值
十九、Java中堆和栈的区别
栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中存储的变量对其它线程是不可见
的。而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。
二十、Java中活锁和死锁有的区别
活锁和死锁类似,不同之处在于处于活锁的线程或进程的状态是不断改变的,活锁可以认为是一种特殊的饥饿。一个现实的活锁例子是两个人在狭小的走廊碰到,两个人都试着避让对方好让彼此通过,但是因为避让的方向都一样导致最后谁都不能通过走廊。简单的说就是,活锁和死锁的主要区别是前者进程的状态可以改变但是却不能继续执行。