创建多线程的几种方式

多线程的形式上实现方式主要有两种,一种是继承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();
                }
            }
        });
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值