Java创建线程的两种方式

ゞ 浴缸里的玫瑰 2023-07-18 02:49 84阅读 0赞

1.Thread类

新建一个线程很简单,只需要new一个Java为我们封装好的Thread类,并且调用它的start()方法即可。

  1. Thread thread = new Thread();
  2. thread.start();

这里的start()方法会新建一个线程并让这个线程执行run()方法,但是在默认情况下,Thread类中的run()方法“什么都没干”,因此,这个线程一启动就马上结束啦,如果我们想让这个新建的线程做点什么,我们就需要继承Thread类并重写run()方法。

  1. class Shopping extends Thread {
  2. public void run() {
  3. System.out.println("血拼");
  4. }
  5. }
  6. public class Test {
  7. public static void main(String[] args) {
  8. Shopping s = new Shopping();
  9. s.start();
  10. }
  11. }

这就是创建自定义线程的第一种方式,继承线程类Thread,并重写run()方法。

因为Java在继承上是单继承的,所以说继承本身也是一种宝贵的资源。但是接口是可以多实现的,因此,我们也可以使用Runnable接口来创建自定义线程。

2.Runnable接口

查看过JDK源码,我们可以发现,Runnable接口只有一个方法,也叫run()方法。

  1. public interface Runnable {
  2. public abstract void run();
  3. }

而且,Thread类有这样一个构造方法:

  1. public Thread(Runnable target) {
  2. init(null, target, "Thread-" + nextThreadNum(), 0);
  3. }

它传入Runnable接口的实例,在start()方法调用时,新的线程就会执行Runnable接口实现类的run()方法

因为实际上Thrad类中的run()方法并不是真的什么都没干(所以上面那个什么都没干是加了双引号的),下面是源码:

  1. public void run() {
  2. if (target != null) {
  3. target.run();
  4. }
  5. }

所以说,默认的Thread类中的run()方法就是在调用Runnable接口实现类的run()方法。

  1. class Shopping implements Runnable {
  2. public void run() {
  3. System.out.println(Thread.currentThread().getName() + "血拼");
  4. }
  5. }
  6. public class Test {
  7. public static void main(String[] args) {
  8. Shopping s = new Shopping();
  9. Thread t1 = new Thread(s);
  10. Thread t2 = new Thread(s);
  11. //新建一个线程,并执行run()方法
  12. t1.start();
  13. //再新建一个线程,并执行run()方法
  14. t2.start();
  15. }
  16. }

这就是创建自定义线程的第二种方式,Shopping类实现了Runnable接口,并将其对象s传入线程对象t1、t2中,最后分别调用t1、t2的start()方法——新建线程并执行run()方法。

如果不考虑线程安全的问题,我们可以用多线程的知识来做小一个实例。

  1. class Shopping implements Runnable {
  2. private int num = 10;
  3. public void run() {
  4. while (true) {
  5. if (num > 0) {
  6. System.out.println(Thread.currentThread().getName() +
  7. "抢血拼到了第" + num-- + "双鞋");
  8. } else
  9. break;
  10. }
  11. }
  12. }
  13. public class Test {
  14. public static void main(String[] args) {
  15. Shopping shopping = new Shopping();
  16. Thread t1 = new Thread(shopping, "线程1");
  17. Thread t2 = new Thread(shopping, "线程2");
  18. t1.start();
  19. t2.start();
  20. }
  21. }

执行结果:

  1. 线程2抢血拼到了第10双鞋
  2. 线程2抢血拼到了第9双鞋
  3. 线程1抢血拼到了第8双鞋
  4. 线程2抢血拼到了第7双鞋
  5. 线程1抢血拼到了第6双鞋
  6. 线程2抢血拼到了第5双鞋
  7. 线程1抢血拼到了第4双鞋
  8. 线程2抢血拼到了第3双鞋
  9. 线程1抢血拼到了第2双鞋
  10. 线程2抢血拼到了第1双鞋

因为是多线程程序,CPU执行哪个线程多一点完全是随机的,所以多次执行的打印结果可能会有不同。

还有可能出现这种情况:

  1. 线程1抢血拼到了第10双鞋
  2. 线程1抢血拼到了第9双鞋
  3. 线程1抢血拼到了第7双鞋
  4. 线程1抢血拼到了第6双鞋
  5. 线程1抢血拼到了第5双鞋
  6. 线程1抢血拼到了第4双鞋
  7. 线程1抢血拼到了第3双鞋
  8. 线程1抢血拼到了第2双鞋
  9. 线程1抢血拼到了第1双鞋
  10. 线程2抢血拼到了第8双鞋

原因在于,语句执行了,控制台没来得及打印。

上面的小实例,已经强调过是不考虑线程安全问题的,但有些人认为不考虑线程安全问题的多线程就不是多线程,所以我们还有继续学习,点击=》多线程线程安全与synchronized关键字

发表评论

表情:
评论列表 (有 0 条评论,84人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java创建线方式

    线程的创建有两种方式,昨天学习过其中的一种: 创建一个类,继承自Java里的[Thread类][Thread],并重写run方法。 最后再创建自定义线程的对象,并调用sta

    相关 Java创建线方式

    创建线程的目的是为了开启一条执行路径,去运行指定的代码和其他代码,实现并行运行。 (实际上时根据操作系统的调度算法,分时间片运行,但由于cpu处理速度很高,宏观上看成时同时