继承Thread类 实现线程的创建(2种写法)
1种写法
public class ThreadDemo03 { static class MyThread extends Thread{ @Override public void run(){ System.out.println("线程名称:" + Thread.currentThread().getName()); } } public static void main(String[] args) { // 创建了线程 Thread t1 = new MyThread(); // 启动线程 t1.start(); System.out.println("当前线程的名称(主线程):" + Thread.currentThread().getName()); } }
2种写法
public class ThreadDemo04 { public static void main(String[] args) { Thread thread = new Thread(){ @Override public void run() { System.out.println("线程名:" + Thread.currentThread().getName()); } }; thread.start(); } }
继承Thread类的创建方式的缺点:在Java语言设计当中只能实现单继承,如果继承了Thread类,就不能继承其他类了,所以这种创建方式在开发中使用。
在Java中不能实现多继承,但是可以实现多接口
1种方法
public class ThreadDemo05 { static class MyRunnable implements Runnable{ @Override public void run() { System.out.println("线程名:" + Thread.currentThread().getName()); } } public static void main(String[] args) { // 1、新建Runnable类 MyRunnable runnable = new MyRunnable(); // 2、新建Thread Thread thread = new Thread(runnable); // 3、启动线程 thread.start(); } }
2种方法
public class ThreadDemo06 { public static void main(String[] args) { // 匿名内部类的方式实现线程 Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("线程名:" + Thread.currentThread().getName()); } }); thread.start(); } }
3种方法
/** * 使用拉姆达表达式的方式创建 * **/ public class ThreadDemo07 { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("线程名: "+ Thread.currentThread().getName()); }); thread.start(); } }
为了拿到执行完线程后可以得到返回值的方法
package Thread; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 创建并得到线程执行的结果 * 实现Callable 接口 + Future容器 的方式 * */ public class ThreadDemo08 { static class MyCallable implements Callable<Integer >{ // 想要返回的是Integer类型 @Override public Integer call() throws Exception { // 生成一个随机数 int num = new Random().nextInt(10); System.out.println("子线程:" + Thread.currentThread().getName() + "随机数:" + num); return num; } } public static void main(String[] args) throws ExecutionException, InterruptedException { // 1、创建一个Callable MyCallable myCallable = new MyCallable(); // 2、创建一个FutureTask 对象来接受返回值 FutureTask<Integer> futureTask = new FutureTask<>(myCallable); // 3、创建Thread Thread thread = new Thread(futureTask); // 启动线程 thread.start(); // 得到线程执行结果 int result = futureTask.get(); System.out.println(String.format("线程名:%s,数字:%d", Thread.currentThread().getName(), result)); } }
Thread.sleep()
TimeUnit.SECONDS.sleep(1)
休眠一秒钟DAYS
表示天,HOURS
表示小时练习:使用连个线程来打印“AABBCCDD”,一个线程只能打印"ABCD"
package Thread; public class ThreadDemo09 { public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { String data = "ABCD"; for (char item:data.toCharArray()) { System.out.print(item); try { // 休眠一段时间 Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t1 = new Thread(runnable); Thread t2 = new Thread(runnable); t1.start(); t2.start(); } }
默认优先级为5
最小优先级为1
最大优先级为10
优先级越大那么它的执行权重越高
理论上优先级越高,执行权限也就越大,但是CPU的调度实很复杂的,所以不会严格按照优先级的排序去执行,但总体还是优先级越高,执行权重越高
守护线程使用场景:Java垃圾回收器、TCP的健康检测
守护线程需要注意的事项: