1.run()和start()的区别
1.start()方法是Java线程约定的内置方法,能够保证代码在新的线程上下文中运行。
2.start()方法包含了创建新线程的特殊代码逻辑。而run()方法一般是我们自己写的代码逻辑,很显然没这个功能。
2.为什么启动一个线程不直接调用run(),而要调用start()启动?
1.如果直接调用run()方法,那么它就只是作为一个普通方法的调用,程序中依然只有一个主线程,并且只能顺序执行,需要等待run()方法执行结束后才能继续执行后面的代码。
2.创建线程的目的是为了更充分地利用CPU里面的资源,如果直接调用run()方法,就失去了创建线程的意义。
3.调用两次start()方法的后果
在Java中,线程的start()方法只能被调用一次,如果第二次调用,就会抛出运行时异常;
因为多次调用start()方法,会被认为是编程错误。
在Java中,线程的运行状态被定义为6个枚举值,分别是:
1新建状态(NEW):线程已经建好,还没调用start()方法。
2.就绪状态(RUNNABLE):线程可能正在运行,也可能在就绪队列等待系统分配CPU资源。
3.阻塞状态(BLOCKED):线程处于等待(Monitor Lock)锁的状态。
4.等待状态(WAITTING):线程处于条件等待状态,当触发后,会被唤醒。
5.计时等待状态(TIMED_WAIT):与等待状态时一样的,只是比等待状态多了一个超时触发机制。
6.终止状态(TERMINATED):表示线程执行结束。
第一次调用start()方法时,线程可能处于终止或这是其他的非NEW状态;这时,当我们再次调用start()方法时,相当于让这个正在运行的线程重新运行一遍,这样无论是从线程安全的角度来看还是从线程本身的执行逻辑来看,都是不合理的。
因此,为了避免这个问题的出现,Java会去判断当前线程的运行状态。
4.如何安全地中断一个正在运行中的线程?
线程是操作系统进行运算调度的最小单位,线程是系统级别的概念。在Java中实现的线程最终的调度都是由操作系统来决定的,JVM只是对操作系统层面的线程做了一层包装。
在JAVA里面调用Thread的start方法,来启动一个线程的时候,只是去告诉操作系统这个线程可以执行,但最终的执行是交给CPU进行执行的,由操作系统的调度算法来决定。
在JAVA的Thread 的API里提供了一个stop方法,可以去强行中止线程,但不安全;线程的任务有可能还没完成,突然中断会导致运行结果不正确的问题。
想要安全地区中断一个线程,只能在线程内部去埋一个“钩子”,外部程序通过钩子来触发对线程的中断的命令;因此,在JAVA 的Thread中,提供了一个叫做interrupt()的方法,这个方法配合isInterrupted()方法来使用,可以去实现线程的安全中断。