欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

创建多线程的几种方式

程序员文章站 2022-07-10 18:30:35
...

多线程的形式上实现方式主要有两种,一种是继承Thread类,一种是实现Runnable接口。本质上实现方式都是来实现线程任务,然后启动线程执行线程任务(这里的线程任务实际上就是run方法)。
继承Thread类
实现线程的第一种方式就是继承Thread类的方式。继承Thread类是最简单的一种实现线程的方式,通过jdk给我们提供的Thread类,重写Thread类的run方法即可,那么当线程启动的时候,就会执行run方法体的内容。
public class ThreadDemo extends Thread {

@Override
public void run() {
    while (true) {
        System.out.println(Thread.currentThread().getName() + " is running ... "); // 打印当前线程的名字
        try {
            Thread.sleep(1000); // 休息1000ms
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public static void main(String[] args) {
    ThreadDemo td = new ThreadDemo();
    td.start(); // 启动线程

    while (true) {
        System.out.println(Thread.currentThread().getName() + " is running ... "); // 打印当前线程的名字
        try {
            Thread.sleep(1000); // 休息1000ms
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

实现Runnable接口
实现Runnable接口也是一种常见的创建线程的方式。使用接口的方式可以让我们的程序降低耦合度。其实Runnable就是一个线程任务,线程任务和线程的控制分离,这也就是上面所说的解耦。我们要实现一个线程,可以借助Thread类,Thread类要执行的任务就可以由实现了Runnable接口的类来处理。 这就是Runnable的精髓之所在!
使用Runnable实现上面的例子步骤如下
定义一个类实现Runnable接口,作为线程任务类
重写run方法,并实现方法体,方法体的代码就是线程所执行的代码
定义一个可以运行的类,并在main方法中创建线程任务类
创建Thread类,并将线程任务类做为Thread类的构造方法传入
启动线程
public class ThreadTarget implements Runnable {

@Override
public void run() {
    while(true) {
        System.out.println(Thread.currentThread().getName() + " is running .. ");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

使用内部类的方式
这并不是一种新的实现线程的方式,只是另外的一种写法。比如有些情况我们的线程就想执行一次,以后就用不到了。那么像上面两种方式都还要再定义一个类,显得比较麻烦,我们就可以通过匿名内部类的方式来实现。使用内部类实现依然有两种,分别是继承Thread类和实现Runnable接口
public class DemoThread {

public static void main(String[] args) {

    // 基于子类的实现
    new Thread() {
        public void run() {
            while (true) {
                System.out.println(Thread.currentThread().getName() + " is running ... "); // 打印当前线程的名字
                try {
                    Thread.sleep(1000); // 休息1000ms
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    }.start();

    // 基于接口的实现
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                System.out.println(Thread.currentThread().getName() + " is running ... "); // 打印当前线程的名字
                try {
                    Thread.sleep(1000); // 休息1000ms
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();

    // 主线程的方法
    while (true) {
        System.out.println(Thread.currentThread().getName() + " is running ... "); // 打印当前线程的名字
        try {
            Thread.sleep(1000); // 休息1000ms
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

定时器
定时器可以说是一种基于线程的一个工具类。可以定时的来执行某个任务。比如要在凌晨的时候汇总一些数据,比如要每隔10分钟抓取一次某个网站上的数据等等,总之计时器无处不在。我们一般将需要定时完成的任务称之为计划任务,这在很多的系统中是非常常见的,比如linux的计划任务,比如Windows下的任务计划等等。我们自己的系统中也需要很多定时执行的也都需要计划任务。最简单的计划任务就可以通过jdk给我提供的API来实现,当然也有很多的计划任务的框架,比如spring的schedule以及著名的quartz。我们这里不去讨论其他的计划任务框架,我们就来看一下jdk所给我们提供的API来实现定时任务。
public class TimerDemo {

private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

public static void main(String[] args) throws Exception {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println("定时任务执行了....");
        }
    }, format.parse("2017-10-11 22:00:00"));
}

}
基于线程池的方式
我们知道,线程和数据库连接这些资源都是非常宝贵的资源。那么每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。当然了,线程池也不需要我们来实现,jdk的官方也给我们提供了API
public static void main(String[] args) {

    // 创建线程池
    ExecutorService threadPool = Executors.newFixedThreadPool(10);

    while(true) {
        threadPool.execute(new Runnable() { // 提交多个线程任务,并执行

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " is running ..");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
相关标签: 多线程实现方式