Java 并发/多线程教程(七)-创建和启动java线程

简介:       本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获。由于个人水平有限,不对之处还望矫正!创建和启动线程在java中创建一个线程如下:Thread thread = new Thread();调用方法start()来启动一个线程:thread.start();         这个例子没有指定线程执行任何代码,线程将会在启动之后停止。

      本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获。由于个人水平有限,不对之处还望矫正!

创建和启动线程

在java中创建一个线程如下:

Thread thread = new Thread();

调用方法start()来启动一个线程:

thread.start();

        这个例子没有指定线程执行任何代码,线程将会在启动之后停止。

        有两种方式指定线程应该执行什么代码。第一种方式就是创建一个Thread的子类并覆写run()方法。第二种方式就是创建一个实现Runnable接口的类。

Thread的子类

      第一种方式指定线程执行什么样的代码,就是创建一个Thread的子类,并且覆写run()方法。在run()方法里的代码就是你调用start()方法后,线程要执行的代码。下面是一个创建Thread子类的例子:

public class MyThread extends Thread{

       @Override

        public void run(){

             System.out.println("MyThread running");

        }

}

为了创建并启动上面的线程,你应该这样做:

MyThread myThread = new MyThread();

myThread.start();

start()方法会在线程开始后立马返回,而不是等到run()方法执行完毕。当run()执行时,就会输出“MyThread running”;

当然,你也可以创建一个Thread的匿名子类,如下:

Thread thread = new Thread(){

      @Override

       public void run(){

                System.out.println("Thread Running");

       }

}

thread.start();

上面的例子当线程被调用时会输出文本“Thread Running".

实现Runnable接口

     第二种方式指定线程应该执行什么样的代码,就是创建一个实现java.lang.Runnable接口的类。这个Runnable对象可以被Thread执行。

     下面是一个实现了Runnable接口的例子:

public class MyRunnable implements Runnable{

      @Override

      public void run(){

            System.out.println("MyRunnable running");

      }

}

因为有了Thread线程执行的run()方法,将MyRunnable的一个实例传给Thread的构造方法。

Thread thread = new Thread(new MyRunnable());

thread.start();

    当线程启动时,会调用MyRunnable实例中的run()方法,而不是Thread自己的run()方法。上面的例子会输出”MyRunnable running".

当然,你也可以创建一个匿名的Runnable接口实例:

Runnable myRunnable = new Runnable(){

        @Override

        public void run(){

               System.out.println("Runnable running");

         }

}

Thread thread = new Thread(myRunnable);

thread.start();

Subclass or Runnable?

       没有明确的规则说这两种方式哪一种是最好的。个人倾向于实现Runnable接口。将实现Runable接口的一个实例交给Thread的实例。当由线程池来执行实现Runnable接口的线程实例时,当线程池没有空闲线程可以调试时,可以让这些线程很好的排队。但是如果执行的是实现Thread的子类的线程实例,那么将会很难做到这一点。

       有时,你可能要同时实现Runnable和Thread子类。例如:创建一个Thread的线程可以执行一个或多个Runable实例,这就是线程池的实现方式。

常见的陷阱:调用run()方法而不是start()方法

      当创建和启动一个线程,通常会犯的一个错误就是调用run()方法,而不是start()方法,如下:

Thread newThread = new Thread(MyRunnable());

newThread.run(); // should be start();

起初,你可能没有注意到什么,因为run()正如你期待的那样被执行了。然而,他并不是被你刚创建的线程所执行。而是被创建线程的线程执行。换句话说,就是执行上面两行代码的线程来执行的run()里的方法。调用线程的使用start()方法。

线程名称

       当你创建一个线程时,你可以给这个线程指定名称。线程名可以让你和其他的线程进行区分。举个例子:

Thread thread = new Thread("New Thread"){

       @override

       public void run(){

              System.out.println("run by:"+getName());

      }

}

thread.start();

System.out.println(thread.getName());

注意,字符串“New Thread"作为一个参数传给Thread的构造器,这个字符串就是线程的名称,这个名称可以通过方法getName()来获取到,你也可以传递参数的方式给一个实现Runnable的接口的线程指定线程名称:如下

MyRunnable runnable = new MyRunnable();

Thread thread = new Thread(runnable,"New Thread");

thread.start();

System.out.println(thread.getName());

注意。MyRunnable不是Thread的一个子类,他不能直接调用Thread的getName()方法。

Thread.currentThread()

Thread.currentThread()方法返回线程正在执行的线程。

Thread thread = Thread.currentThread();

只要获取到当前运行线程,你就可以在此基础上进行方法的调用。例如:你可以获取到当前正在执行线程的名称。

String threadName = Thread.currentThread().getName();

Java Thread example

这里有一个小例子。首先输出执行main方法的线程名称。这个线程是由JVM指定的。然后开启10个线程,并以”“+i作为他们的线程名。每个线程输出他们的名字后,然后停止。

public class ThreadExample{

     public static void main(String[] args){

           System.out.println(Thread.currentThread().getName());

           for(int i=0;i<10;i++){

              new Thread(""+i){

                   public void run(){

                       System.out.println("Thread:"+getName()+"running");

                   }

             }.start();

         }

      }

}

注意。线程并不是有序执行的。也就是说线程1并不是第一个执行的线程,这是因为线程的执行原则是并行的,而不是有序的,JVM和操作系统决线程的调度顺序。当他们调度时顺序是不固定的。

目录
相关文章
|
5月前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
168 4
|
5月前
|
缓存 安全 Java
如何理解Java中的并发?
Java并发指多任务交替执行,提升资源利用率与响应速度。通过线程实现,涉及线程安全、可见性、原子性等问题,需用synchronized、volatile、线程池及并发工具类解决,是高并发系统开发的关键基础。(238字)
326 5
|
8月前
|
SQL 缓存 安全
深度理解 Java 内存模型:从并发基石到实践应用
本文深入解析 Java 内存模型(JMM),涵盖其在并发编程中的核心作用与实践应用。内容包括 JMM 解决的可见性、原子性和有序性问题,线程与内存的交互机制,volatile、synchronized 和 happens-before 等关键机制的使用,以及在单例模式、线程通信等场景中的实战案例。同时,还介绍了常见并发 Bug 的排查与解决方案,帮助开发者写出高效、线程安全的 Java 程序。
450 0
|
8月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
428 83
|
8月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
356 0
|
8月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
467 83
|
9月前
|
Java 物联网 数据处理
Java Solon v3.2.0 史上最强性能优化版本发布 并发能力提升 700% 内存占用节省 50%
Java Solon v3.2.0 是一款性能卓越的后端开发框架,新版本并发性能提升700%,内存占用节省50%。本文将从核心特性(如事件驱动模型与内存优化)、技术方案示例(Web应用搭建与数据库集成)到实际应用案例(电商平台与物联网平台)全面解析其优势与使用方法。通过简单代码示例和真实场景展示,帮助开发者快速掌握并应用于项目中,大幅提升系统性能与资源利用率。
258 6
Java Solon v3.2.0 史上最强性能优化版本发布 并发能力提升 700% 内存占用节省 50%
|
9月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
641 5
|
9月前
|
监控 搜索推荐 Java
Java 多线程最新实操技术与应用场景全解析:从基础到进阶
本文深入探讨了Java多线程的现代并发编程技术,涵盖Java 8+新特性,如CompletableFuture异步处理、Stream并行流操作,以及Reactive编程中的Reactor框架。通过具体代码示例,讲解了异步任务组合、并行流优化及响应式编程的核心概念(Flux与Mono)。同时对比了同步、CompletableFuture和Reactor三种实现方式的性能,并总结了最佳实践,帮助开发者构建高效、扩展性强的应用。资源地址:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
508 3

热门文章

最新文章