1.线程创建
1.继承Thread重写run方法。
2.通过实现Runnable接口重写run方法。
3.通过匿名内部类。
4.通过lambda表达式。
class MyThread extends Thread{
@Override
public void run() {
System.out.println("继承Thread重写run");
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("实现Runnbale接口重写run方法");
}
}
public class Demo1 {
public static void main (String[] args) {
//继承Thread重写run方法
Thread thread1 = new MyThread();
thread1.start();
//通过实现Runnable接口重写run方法
Runnable runnable = new MyRunnable();
Thread thread2 = new Thread(runnable);
thread2.start();
//通过匿名内部类
Thread thread3 = new Thread(){
@Override
public void run() {
System.out.println("通过Thread匿名内部类");
}
};
Thread thread4 = new Thread(new Runnable(){
@Override
public void run() {
System.out.println("通过Runnable匿名内部类");
}
});
thread3.start();
thread4.start();
//通过lambda表达式
Thread thread5 = new Thread(()->{
System.out.println("通过lambda表达式");
});
thread5.start();
}
}
2.线程中断
2.1使用自己的标志位来使线程中断。
public class Demo1 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
while (!Thread.currentThread().isInterrupted()) {
System.out.println("正在执行任务");
}
System.out.println("线程已退出");
});
t1.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("线程准备退出");
t1.interrupt();
}
}
2.2使用Thread自带的标志位来使线程中断。
使用Thread.currentThread().isInterrupted(),判断后不会清除标志位。
public class Demo1 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
while (Thread.currentThread().isInterrupted()) {
System.out.println("正在执行任务");
}
System.out.println("线程已退出");
});
t1.start();
t1.interrupt();
}
}
使用Thread.interrupted判断后会清除标志位。
public class Demo1 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
while (Thread.interrupted()) {
System.out.println("正在执行任务");
}
System.out.println("线程已退出");
});
t1.start();
t1.interrupt();
}
}
这里的interrupt方法有两种情况。
1.如果线程未阻塞,会修改标志位。
2.如果线程阻塞,则会使线程内部的阻塞方法触发一个InterruptedException。
3.线程等待
join,如果被等待的线程还没有执行完,那就等待,如果执行完就直接返回。
join还可以设置最大等待时间,如果在时间内没有执行完就不在等待。
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
System.out.println(Thread.currentThread().getName() + "开始");
Thread.sleep(5000);
for (int i = 0; i < 2000; i++) {
}
System.out.println(Thread.currentThread().getName() + "执行完毕");
});
Thread t2 = new Thread(()->{
System.out.println(Thread.currentThread().getName() + "开始");
Thread.sleep(5000);
for (int i = 0; i < 2000; i++) {
}
System.out.println(Thread.currentThread().getName() + "执行完毕");
});
t1.start();
//使主线程等待t1执行完毕
t1.join();
t2.start();
//使主线程等待t2执行完毕,最大等待时间为4s
t2.join(4000);
System.out.println("主线程结束");
}
}
4.线程休眠
通过sleep,能够让线程休眠一会,使线程从就绪队列进入阻塞队列,等待sleep时间结束就会被调度回就绪队列。
public class Demo1 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
System.out.println("休眠开始,休眠1s");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("休眠结束");
});
t1.start();
}
}
5.获取线程实例
如果是继承Thread然后重写run方法在run方法中this即可,其他的就需要通过调用Thread.currentThread()获取线程的引用。
public class Demo1 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
System.out.println(Thread.currentThread().getName());
},"线程1");
t1.start();
}
}