Java 多线程

多线程创建的两种方式:

♠①:创建一个类继承Thread类,并重写run方法。

  1. public class MyThread extends Thread {
  2. @Override
  3. public void run() {
  4. for (int i = 0; i < 100; i++) {
  5. System.out.println(getName() + ":打了" + i + "个小兵");
  6. }
  7. }
  8. }

来写个测试方法验证下:

  1. //创建MyThread对象
  2. MyThread t1=new MyThread();
  3. MyThread t2=new MyThread();
  4. MyThread t3=new MyThread();
  5. //设置线程的名字
  6. t1.setName("鲁班");
  7. t2.setName("刘备");
  8. t3.setName("亚瑟");
  9. //启动线程
  10. t1.start();
  11. t2.start();
  12. t3.start();

来看一下执行后的结果:
Java多线程简单入门 - 图1

♠②:创建一个类实现Runnable接口,并重写run方法。

  1. public class MyRunnable implements Runnable {
  2. @Override
  3. public void run() {
  4. for (int i = 0; i < 10; i++) {
  5. try {//sleep会发生异常要显示处理
  6. Thread.sleep(20);//暂停20毫秒
  7. } catch (InterruptedException e) {
  8. e.printStackTrace();
  9. }
  10. System.out.println(Thread.currentThread().getName() + "打了:" + i + "个小兵");
  11. }
  12. }
  13. }

写个测试方法验证下:

  1. //创建MyRunnable类
  2. MyRunnable mr = new MyRunnable();
  3. //创建Thread类的有参构造,并设置线程名
  4. Thread t1 = new Thread(mr, "张飞");
  5. Thread t2 = new Thread(mr, "貂蝉");
  6. Thread t3 = new Thread(mr, "吕布");
  7. //启动线程
  8. t1.start();
  9. t2.start();
  10. t3.start();

来看一下执行后的结果:
Java多线程简单入门 - 图2

❤1、为什么要重写run方法?

因为run方法是用来封装被线程执行的代码。

❤2、run()方法和start()方法有什么区别?

  • run():封装线程执行的代码,直接调用相当于调用普通方法。
  • start():启动线程,然后由JVM 调用此线程的 run() 方法。

    ❤3、通过继承 Thread 的方法和实现 Runnable 接口的方式创建多线程,哪个好?

    实现Runable接口好,原因有两个:

  • ♠①、避免了Java单继承的局限性

  • ♠②、适合多个相同的程序代码去处理同一资源的情况,把线程、代码和数据有效的分离,更符合面向对象的设计思想。

针对线程控制,还会遇到 3 个常见的方法,来一一介绍下。
1)sleep():使当前正在执行的线程暂停指定的毫秒数,也就是进入休眠的状态。
需要注意的是,sleep 的时候要对异常进行处理。

  1. try {//sleep会发生异常要显示处理
  2. Thread.sleep(20);//暂停20毫秒
  3. } catch (InterruptedException e) {
  4. e.printStackTrace();
  5. }

2)join():等待这个线程执行完才会轮到后续线程得到cpu的执行权,使用这个也要抛出异常。

  1. //创建MyRunnable类
  2. MyRunnable mr = new MyRunnable();
  3. //创建Thread类的有参构造,并设置线程名
  4. Thread t1 = new Thread(mr, "张飞");
  5. Thread t2 = new Thread(mr, "貂蝉");
  6. Thread t3 = new Thread(mr, "吕布");
  7. //启动线程
  8. t1.start();
  9. try {
  10. t1.join(); //等待t1执行完才会轮到t2,t3抢
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. t2.start();
  15. t3.start();

来看一下执行后的结果:
Java多线程简单入门 - 图3
3)setDaemon():将此线程标记为守护线程,准确来说,就是服务其他的线程,像 Java 中的垃圾回收线程,就是典型的守护线程。

  1. //创建MyRunnable类
  2. MyRunnable mr = new MyRunnable();
  3. //创建Thread类的有参构造,并设置线程名
  4. Thread t1 = new Thread(mr, "张飞");
  5. Thread t2 = new Thread(mr, "貂蝉");
  6. Thread t3 = new Thread(mr, "吕布");
  7. t1.setDaemon(true);
  8. t2.setDaemon(true);
  9. //启动线程
  10. t1.start();
  11. t2.start();
  12. t3.start();

如果其他线程都执行完毕,main 方法(主线程)也执行完毕,JVM 就会退出,也就是停止运行。如果 JVM 都停止运行了,守护线程自然也就停止了。
最后再来看一下线程的生命周期。
Java多线程简单入门 - 图4