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和操作系统决线程的调度顺序。当他们调度时顺序是不固定的。

目录
相关文章
|
1天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
2天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
3天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
3天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
3天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
38 2
|
3天前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
14 1
|
2月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
60 1
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
32 3
|
2月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
25 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
41 2