多线程相关问题(一)
2019-02-09 本文已影响142人
NealLemon
由于近期在做知识储备,在做很多的复习,把之前看过的内容重温一遍真的像重新看一遍一样,真的是一入JAVA深似海。
概念相关问题
1.线程和进程有什么区别?
线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。
2.线程的状态有哪些?
Java线程状态转换.jpg相关方法问题
1.start和run方法的区别?
在这里我们先写一段代码来实际感受一下这两个方法的区别。
/**
* 针对run()和 start()区别的测试类
*/
public class ThreadTest {
/**
* 单纯打印执行内容以及当前线程的线程名
*/
private static void doTest(String name) {
System.out.println("使用"+ name + "方法调用doTest()");
System.out.println("Current Thread is : " + Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread startThread = new Thread() {
@Override
public void run() {
doTest("start()");
}
};
Thread runThread = new Thread() {
@Override
public void run() {
doTest("start()");
}
};
startThread.start();
runThread.run();
}
}
执行结果
结果.png
具体分析
我们先来看一下java.lang.Thread#start
方法的源码
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 */
}
}
}
上述源码中 实际启动的就是 start0();
这个方法。我们查看源码可以看到 这个方法也是一个native方法。
private native void start0();
我们接着查看一下native中的相关源码。这里就直接给出源码以及重点,具体怎么查询的可以自行百度。
start.png start1.png由上述的虚拟机源码,我们可以就可以看明白刚刚我们写的demo中的结果的原因了。
总结
图解:
总结.png- 调用start()时,会创建一个新的子进程并启动
- 调用run()时,支持thread的普通方法调用,依旧在主线程中调用。
2.sleep()和wait()的区别?
- sleep()是Thread类的方法,wait()是Object类中定义的方法。
- sleep()方法可以在任何地方使用,wait()只能在synchronized方法或代码快中使用
- Thread.sleep 只会让出cpu,不会导致锁行为的改变
- Object.wait不仅让出cpu,还会释放已经占有的同步锁资源
3.notify() 和 notifyAll()的区别?
首先需要了解一下两个概念。
锁池
锁池.png等待池
等待池.png- notifyAll()让所有处于等待池的线程全部进入锁池去竞争锁的机会
- notify() 会随机选择一个线程进入锁池去竞争。
4.yield和join的区别?
- 一个调用yield()方法的线程告诉虚拟机它乐意让其他线程占用自己的位置。这表明该线程没有在做一些紧急的事情。注意,这仅是一个暗示,并不能保证不会产生任何影响。
- 得一个线程在另一个线程结束后再执行。如果join()方法在一个线程实例上调用,当前运行着的线程将阻塞直到这个线程实例完成了执行。
5.调用Interrupt()函数
- 如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。
- 如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,被设置中断标志的线程将继续正常运行。不受影响。
- 需要被调用的线程配合中断
- 在正在运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程。