Thread 启动 暂停 停止 优先级 安全
线程与进程的概念
- 进程:
- 线程:使用多线程也就是在使用异步。
- 守护线程:非守护线程的保姆,GC垃圾回收器。(调用方法setDaemo())
- 线程实现方法:继承Thread类(Thread类也实现了Runnable接口)、实现Runnable接口。前者不能实现多继承,需要多继承时使用第二种方法,实际上这两种方法创建的线程功能是一样的。
Thread类的使用
线程随机性
public class thread1 {
public static void main(String[] args) {
MyThread mt = new MyThread();
//start运行耗时
mt.start();
/* 1通过jvm告诉操作系统创建Thread
* 2操作系统开辟内存,创建Thread对象
* 3操作系统对Thread对象进行调度,确定执行时机
* 4Thread成功被执行
*/
System.out.println("over");
//使用多线程技术时,输出结果和代码的执行顺序没有必然联系。此次是先输出over,可以使用sleep方法,达到
//先后输出over的目的
}
}
class MyThread extends Thread {
public void run() {
super.run();
System.out.println("i am thread1");
}
}

执行start的顺序不代表执行run的顺序
public class thread2 {
public static void main(String[] args) {
MyThread th0 = new MyThread(1);
MyThread th1 = new MyThread(2);
MyThread th2 = new MyThread(3);
MyThread th3 = new MyThread(4);
MyThread th4 = new MyThread(5);
th0.start();
th1.start();
th2.start();
th3.start();
th4.start();
}
}
class MyThread extends Thread{
private int i;
public MyThread(int i) {
super();
this.i=i;
}
public void run() {
System.out.println(i);
}
}

Runable接口的使用(多继承)
当想创建的线程类有父类时,不能再继承Thread类,可以继承Runnable接口。
package thread;
public class Runnable1 {
public static void main(String[] args) {
Dog dog = new Dog();
Thread thread = new Thread(dog);
thread.start();
}
}
class Dog extends Animal implements Runnable {
@Override
public void run() {
System.out.println(this.num);
}
}
class Animal {
public int num = 10;
}

实现Runnable接口的内部流程
Runnable runnable = new Runnable();
Thread thread = new Thread(runnable);
thread.start();
先调用Thread.java类的run方法
public void run(){
if(target != null){
target.run;
}
}
target就是实现Runnable接口的对象,该对象被init方法初始化,而init方法在Thread.java的构造方法中被调用。
常用API
- start:告诉系统某个线程准备就绪,可以安排一个时间来执行,执行时自动调用run方法。
即,开启新线程执行run方法。 - run:不开启新线程,使用当前进程。
- yield:进程放弃时间片
- currentThread
public class Thread4 {
public static void main(String[] args) throws InterruptedException {
Thread1 th1 = new Thread1();
th1.start();
Thread1.sleep(1000);
System.out.println("-----");
th1.run();
}
}
class Thread1 extends Thread{
public Thread1() {
System.out.println("构造方法 "+Thread.currentThread().getName());
}
public void run() {
System.out.println("run方法 "+Thread.currentThread().getName());
}
}

- isAlive 判断当前线程是否存活
- sleep 让当前正在执行的线程休眠
要理解当前正在执行的进程这几个字的含义。
package thread;
public class ThreadDemo04 {
public static void main(String[] args) throws Exception {
Thread4 th4 =new Thread4();
Thread.sleep(2000);
th4.start();
//本以为这里睡眠的是新开辟的进程Thread-0 但是输出结果显示睡眠的还是main方法所在的进程。
//当前执行的进程是main所在的进程,即 Thread.currentThread().sleep()
//尽管sleep是被th4调用的,单它处理的任然是main线程
th4.sleep(2000);
System.out.println("执行打印方法的进程是"+Thread.currentThread().getName()+System.currentTimeMillis());
}
}
class Thread4 extends Thread{
public Thread4() {
System.out.println("执行构造方法的进程是"+Thread.currentThread().getName()+"当前时间"+System.currentTimeMillis());
}
public void run() {
System.out.println("执行start调用run方法的进程是"+Thread.currentThread().getName()+"当前时间"+System.currentTimeMillis());
}
}

- 调整了Thread.sleep 的位置
package thread;
public class ThreadDemo04 {
public static void main(String[] args) throws Exception {
Thread4 th4 =new Thread4();
Thread.sleep(2000);
th4.start();
System.out.println("执行打印方法的进程是"+Thread.currentThread().getName()+System.currentTimeMillis());
}
}
class Thread4 extends Thread{
public Thread4() {
System.out.println("执行构造方法的进程是"+Thread.currentThread().getName()+"当前时间"+System.currentTimeMillis());
}
public void run() {
System.out.println("执行start调用run方法的进程是"+Thread.currentThread().getName()+"当前时间"+System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("执行start调用run方法的进程是"+Thread.currentThread().getName()+"睡眠后时间"+System.currentTimeMillis());
}
}
第二行和第三行是同时输出的

- getId 取得线程的唯一标识
停止线程 interrupt(stop不安全) 暂停 suspend resume
stop直接销毁线程对象
判断状态
interrupt 只是做了一个停止标记,不是真正的停止线程
interrupted
isInterrupted
- interrupted 判断是否中断并清除中断状态 类似sleep 作用于当前执行的线程,而不是调用它的线程。
/**
* Tests whether the current thread has been interrupted. The
* <i>interrupted status</i> of the thread is cleared by this method. In
* other words, if this method were to be called twice in succession, the
* second call would return false (unless the current thread were
* interrupted again, after the first call had cleared its interrupted
* status and before the second call had examined it).
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if the current thread has been interrupted;
* <code>false</code> otherwise.
* @see #isInterrupted()
* @revised 6.0
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
- isInterrupted
/**
* Tests whether this thread has been interrupted. The <i>interrupted
* status</i> of the thread is unaffected by this method.
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if this thread has been interrupted;
* <code>false</code> otherwise.
* @see #interrupted()
* @revised 6.0
*/
public boolean isInterrupted() {
return isInterrupted(false);
}
测试
public class ThreadDemo06 {
public static void main(String[] args) {
Thread06 th6 = new Thread06();
th6.start();
System.out.println("中断前th6是否存活:"+th6.isAlive());
th6.interrupt();
System.out.println("调用th6.isInterrupted():是否中断"+th6.isInterrupted());
System.out.println("中断后th6是否存活:"+th6.isAlive());
System.out.println("第一次调用th6.interrupted():是否中断"+th6.interrupted());
System.out.println("第二次调用th6.interrupted():是否中断"+th6.interrupted());
}
}
class Thread06 extends Thread {
public void run() {
for(int i=1;i<=10;i++) {
System.out.println(i);
}
}
}

- 中断当前进程
public class ThreadDemo06 {
public static void main(String[] args) {
Thread06 th6 = new Thread06();
th6.start();
Thread.currentThread().interrupt();
//interrupted 即使是th6调用 指的也是当前正在的main进程
System.out.println("第一次调用th6.interrupted():是否中断"+th6.interrupted());
System.out.println("第二次调用th6.interrupted():是否中断"+th6.interrupted());
}
}

停止线程–异常停止法
isInterrupted 和 interrupted是为了判断该位置的线程是否应该中断,interrupt作为一个标志本身不具有中断线程的能力,可以将要执行的代码放到if(interrupted/isInterrupterd)else{}结构中,达到停止目的。
- 异常停止法
public class ThreadDemo07 {
public static void main(String[] args) throws InterruptedException {
Thread7 th7 = new Thread7();
th7.start();
Thread.sleep(2000);
th7.interrupt();
}
}
class Thread7 extends Thread {
public void run() {
try {
for (int i = 1; i <= 10; i++) {
if (Thread.interrupted()) {
System.out.println("线程停止,要退出了");
throw new InterruptedException();
}
System.out.println(i);
//Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("进入到Thread7的run方法中");
e.printStackTrace();
}
}
}
主进程中途睡眠2秒,Thread7的run方法中的循环已经执行完毕(先执行start,输出1–10),两秒后作出停止线程的标记,此时循环执行完毕不会出现异常。

- 下图是主进程没有睡眠的情况

- 当sleep和interrupt相遇时会报错

优先级 setPriority() 1~10
- 优先级高线程获得的CPU资源更多,分配到时间片更多,但不代表高优先级的一定先执行完(大多数情况)。
- 当优先级差距很大时,调用顺序和实行结果顺序没有必然联系。
public class Thread08 {
public static void main(String[] args) {
T1 t1 = new T1();
t1.setPriority(1);
T2 t2 = new T2();
t2.setPriority(10);
t1.start();
t2.start();
}
}
class T1 extends Thread {
public void run() {
for (int i = 0; i <= 100; i++) {
System.out.println("t1-" + "i=" + i);
}
}
}
class T2 extends Thread {
public void run() {
for (int i = 0; i <= 100; i++) {
System.out.println("t2-" + "i=" + i);
}
}
}

本文详细介绍了Java线程的基础概念,包括线程与进程的区别,守护线程的作用,以及如何通过继承Thread类或实现Runnable接口来创建线程。探讨了线程的随机性,优先级设置,线程的启动、暂停和停止方法,并解释了interrupt和isInterrupted等API的使用,帮助读者深入理解Java线程的管理和控制。
1509

被折叠的 条评论
为什么被折叠?



