调用thread的start方法,由下面代码可以看出构造方法是由main线程调用的,而run()方法是由Thread-0线程调用的
从下面代码可以看出,都是main线程调用的
调用thread的run()并不是启动线程,而是就是单纯的调用这个方法,isAlive()测试这个线程是否活着。 如果一个线程已经启动并且尚未死亡,那么线程是活着的。
由于调用run()方法并不是启动一个线程,而是相当于调用了一个方法,所以返回false,而start()相当于是启动一个线程,所以返回true。
public static void sleep(long millis ) throws InterruptedException;
使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程
序的精度和准确性。 线程不会丢失任何显示器的所有权。
由于在调用run方法时,是在当前线程中执行,所以会一次执行,而使用start方法,是又创建了一个新的线程,所以在两个线程相互不影响,main线程会直接执行。
public long getId()
返回此线程的标识符。 线程ID是创建此线程时生成的正数long号。 线程ID是唯一的,并且在其生命周期内保持不变。 当线程被终止时,该线程ID可以被重用。
线程的停止:
在java中有以下的3种方法可以终止正在运行的线程:
1)使用退出标志,使线程正常退出也就是在run方法完成后线程停止。
2)使用stop方法强制停止线程,但是不推荐使用,因为他和suspend及resume一样都是要过期作废的方法,使用他们可能产生不可预料的结果。
3)使用interrupt方法中断线程。
从上面的方法可以看出,interrupt()方法,并没有让线程终止。因为它不像for+break可以马上停止循环,只不过调用interrupt()相当于在线程中做了一个停止标记。
线程停止的判断:
Thread.java中有两个方法判断线程的运行情况:
1)、interrupted();测试当前线程是否已经中断
public static boolean interrupted()
2)、isInterrupted();测试线程是否已经中断
public boolean isInterrupted()
由以上的两个方法看出的区别:interrupt()会标识停止标记,interrupted()判断是否线程中断,但是在第二个输出时候为false,是因为在执行interrupted()的时候会清除线程中断标记,再次调用interrupted()的时候线程中断标识已经不存在,故返回false;而isInterrupted()方法不会清除线程中断标识,所以无论调用多少次都是返回true。
线程终止
- 异常法
interrupt()将线程标识为终止标记,当线程看到这个标记的时候就会触发终止,会在把该run()方法中下面的代码执行完在终止,类似于有延迟,而不是立刻终止;要想立刻中断线程,可以抛出异常。
2. 在sleep中,终止线程
在sleep状态下停止某一个线程会进入catch
3. 暴力终止
直接调用stop()
stop()方法过时了;调用stop()会导致代码逻辑不完整
这段代码的逻辑,子线程是一个匿名内部类,它的run方法在执行时会休眠1秒钟,然后再执
行后续的逻辑,而主线程则是休眠0.1秒后终止子线程的运行,也就是说,JVM在执行
thread.stop()时,子线程还在执行sleep(1000),此时stop方法会清除栈内信息,结束该
线程,这也导致了run方法的逻辑不完整,输出语句println代表的是一段逻辑,可能非常重
要,比如子线程的主逻辑,资源回收,情景初始化等等,但是因为stop线程了,这些就都不再
执行了,于是就产生了业务逻辑不完整的情况.
破坏了原子逻辑
多线程为了解决共享资源抢占的问题,使用了锁的概念,避免资源不同步,但是正是因为此原因,stop方法却会带来更大的麻烦,它会丢弃所有的锁,导致原子逻辑受损。
使用return终止线程
线程的暂停
线程的暂停意味着是可以恢复的,在java多线程中,可以使用suspend()方法暂停线程,使用resume()方法恢复线程的执行
控制台输出的前两条数据可以看出来线程确实被暂停了
suspend()方法使用不当可能会导致独占
printing()方法是线程安全的,只不过是如果线程名字是a的调用会导致,这个线程在这里挂起,如果别的线程访问的是同一个Running对象会导致阻塞,类似于死锁,只有把线程a恢复,也就是调用resume()。
线程的优先级
在操作系统中,优先级越高的线程越容易获取cpu的执行权,线程的优先级是有几成关系的
守护线程 =后台线程=daemon
当系统中只有守护线程的时候,整个系统就结束了,main方法是前台线程