1.创建线程
(1)通过继承Thread类,重写run方法。
(2)通过Runnable接口,把Runnable接口的值赋给Thread(Runnable本质上还是要搭配Thread来使用,只不过是换了一种指定任务的方式,Runnable只是定义一个要执行的任务,也可以搭配其他类来使用,使用Runnable可以更好的解耦合)
(3)通过匿名Thread类来创建线程(本质上同(1))
(4)通过匿名Runnable类来创建线程(本质上同(2))
(5)通过lambda表达式来创建线程
Thread t3 = new Thread(new MyRunnable());
Thread t4 = new Thread(new MyRunnable(), "这是我的名字"); 创建线程并且命名
定义一个要执行的任务,Runnable表示一个可以运行的东西,具体就通过run方法来表示运行的实际代码。
注:调用start()才是创建线程(才有新的执行流),调用run()只是一个普通的方法调用,不涉及创建新的线程。 所以不应该手动调用run(),run()方法是由start()内部来调用的。
2.中断一个线程
目前常见的有两种方法:
(1)通过 thread 对象调用 interrupt() 方法通知该线程停止运行
(2)thread 收到通知的方式有两种:
不是调用了Interrupt方法,对应的线程就一定被终止,还是要看代码怎么写的。
public class Thread2 {
private static class MyRunnable implements Runnable {
@Override
public void run() {
// 两种方法均可以
//while (!Thread.interrupted()) { 和下面的比较调用后自动清除标记位
while (!Thread.currentThread().isInterrupted()) {//Thread类里内置的标记位,不用用户自己创建代码来判断。 和上面的比较调用后不会自动清楚标记位
System.out.println(Thread.currentThread().getName()
+ ": 别管我,我忙着转账呢!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName()
+ ": 有内鬼,终止交易!");
break; //如果涉及到了 wait/join/sleep()等方法而阻塞 就一定要有break不然线程不会结束 interrupt只是通知线程中断 真正的中断还是要根据线程自身的方法来决定。
}
}
System.out.println(Thread.currentThread().getName()
+ ": 啊!险些误了大事");
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable target = new MyRunnable();
Thread thread = new Thread(target, "李四");
System.out.println(Thread.currentThread().getName()
+ ": 让李四开始转账。");
thread.start();
Thread.sleep(10 * 1000);
System.out.println(Thread.currentThread().getName()
+ ": 老板来电话了,得赶紧通知李四对方是个骗子!");
thread.interrupt();
}
}
3.等待线程
当我们创建许多个线程后,每个线程都是一个独立的执行流,这些线程的执行顺序都是不确定的,完全是取决于操作系统调度的。
等待线程机制就是可以确定线程的“结束顺序”可以保证线程1一定先于线程2结束
thread1.start();
thread1.join();
thread2.star();
thread2.join();
join()起到的作用就是等待某个线程结束,谁调用join()就等待谁结束,当调用join()的线程执行完毕后join()就不会阻塞了。
public void join(long mills)这个等待还可以设置时间 不是无限的等 超过了等待时间还没结束 就不等了
Thread currentThread();返回当前线程对象的引用,在哪个线程中调用,就返回那个线程对象的引用。
4.休眠当前线程
5.线程的状态(反应当前线程正在干什么)
线程的状态是一个枚举类型,Thread.State
这里的状态指的是Java Threa类的状态能一定程度上反应出操作系统中线程的状态,但是也不绝对。
状态:
NEW:Thread对象刚创建,还没在系统中创建线程。相当于任务交给了线程,但是线程还没有开始执行。
RUNNABLLE:线程是一个准备就绪的状态,随时可能调度到CPU上执行,或者重在CPU上执行(线程的Task Struck在就绪队列中)
BLOCKED/WAITING/TIMED-WAITING:线程当前已阻塞了。(此处这三个状态对应着不同的阻塞原因)
terminalted:系统中的线程已经结束了(入口方法执行完毕)。Thread对象还没有被销毁