首页 > 编程语言 >04.如何创建并运行java线程

04.如何创建并运行java线程

时间:2023-06-04 23:06:55浏览次数:32  
标签:Runnable run 04 Thread start 线程 java 源代码


评:
原文链接 译者:章筱虎 校对:方腾飞

Java线程类也是一个object类,它的实例都继承自java.lang.Thread或其子类。 可以用如下方式用java中创建一个线程:

查看源代码打印帮助
1 Tread thread = new Thread();
执行该线程可以调用该线程的start()方法:

查看源代码打印帮助
1 thread.start();

在上面的例子中,我们并没有为线程编写运行代码,因此调用该方法后线程就终止了。

编写线程运行时执行的代码有两种方式:一种是创建Thread子类的一个实例并重写run方法,第二种是创建类的时候实现Runnable接口。接下来我们会具体讲解这两种方法:

创建Thread的子类

创建Thread子类的一个实例并重写run方法,run方法会在调用start()方法之后被执行。例子如下:

查看源代码打印帮助

1 public class MyThread extends Thread { 


2 public void run(){ 


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


4 } 


5 }


可以用如下方式创建并运行上述Thread子类

查看源代码打印帮助
1 MyThread myThread = new MyThread();

2 myTread.start();
一旦线程启动后start方法就会立即返回,而不会等待到run方法执行完毕才返回。就好像run方法是在另外一个cpu上执行一样。当run方法执行后,将会打印出字符串MyThread running。

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

查看源代码打印帮助

1 Thread thread = new Thread(){ 


2 public void run(){ 


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


4 } 


5 };


6 thread.start();
当新的线程的run方法执行以后,计算机将会打印出字符串”Thread Running”。

实现Runnable接口

第二种编写线程执行代码的方式是新建一个实现了java.lang.Runnable接口的类的实例,实例中的方法可以被线程调用。下面给出例子:

查看源代码打印帮助

1 public class MyRunnable implements Runnable { 


2 public void run(){ 


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


4 } 


5 }


为了使线程能够执行run()方法,需要在Thread类的构造函数中传入 MyRunnable的实例对象。示例如下:

查看源代码打印帮助
1 Thread thread = new Thread(new MyRunnable());

2 thread.start();
当线程运行时,它将会调用实现了Runnable接口的run方法。上例中将会打印出”MyRunnable running”。

同样,也可以创建一个实现了Runnable接口的匿名类,如下所示:

查看源代码打印帮助

1 Runnable myRunnable = new Runnable(){ 


2 public void run(){ 


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


4 } 


5 } 


6 Thread thread = new Thread(myRunnable); 


7 thread.start();


创建子类还是实现Runnable接口?

对于这两种方式哪种好并没有一个确定的答案,它们都能满足要求。就我个人意见,我更倾向于实现Runnable接口这种方法。因为线程池可以有效的管理实现了Runnable接口的线程,如果线程池满了,新的线程就会排队等候执行,直到线程池空闲出来为止。而如果线程是通过实现Thread子类实现的,这将会复杂一些。

有时我们要同时融合实现Runnable接口和Thread子类两种方式。例如,实现了Thread子类的实例可以执行多个实现了Runnable接口的线程。一个典型的应用就是线程池。

常见错误:调用run()方法而非start()方法

创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:

查看源代码打印帮助
1 Thread newThread = new Thread(MyRunnable());

2 newThread.run(); //should be start();
起初你并不会感觉到有什么不妥,因为run()方法的确如你所愿的被调用了。但是,事实上,run()方法并非是由刚创建的新线程所执行的,而是被创建新线程的当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。

线程名

当创建一个线程的时候,可以给线程起一个名字。它有助于我们区分不同的线程。例如:如果有多个线程写入System.out,我们就能够通过线程名容易的找出是哪个线程正在输出。例子如下:

查看源代码打印帮助
1 MyRunnable runnable = new MyRunnable();

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

3 thread.start();

4 System.out.println(thread.getName());
需要注意的是,因为MyRunnable并非Thread的子类,所以MyRunnable类并没有getName()方法。可以通过以下方式得到当前线程的引用:

查看源代码打印帮助
1 Thread.currentThread();
因此,通过如下代码可以得到当前线程的名字:

查看源代码打印帮助
1 String threadName = Thread.currentThread().getName();
线程代码举例:
这里是一个小小的例子。首先输出执行main()方法线程名字。这个线程JVM分配的。然后开启10个线程,命名为1~10。每个线程输出自己的名字后就退出。

查看源代码打印帮助

01 public class ThreadExample { 


02 public static void main(String[] args){ 


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


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


05 new Thread("" + i){ 


06 public void run(){ 


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


08 } 


09 }.start(); 


10 } 


11 } 


12 }


需要注意的是,尽管启动线程的顺序是有序的,但是执行的顺序并非是有序的。也就是说,1号线程并不一定是第一个将自己名字输出到控制台的线程。这是因为线程是并行执行而非顺序的。Jvm和操作系统一起决定了线程的执行顺序,他和线程的启动顺序并非一定是一致的。

(全文完)


--------------------------------------------------------------------------------

支持本站::Pay For Your Wish

标签:Runnable,run,04,Thread,start,线程,java,源代码
From: https://blog.51cto.com/u_16080829/6412769

相关文章

  • Java URL正则表达式
    评:网上转贴的Java正则很让人失望,一篇JavaScript正则集录被很多人当成Java正则表达式转来转去,我擦,太坑爹了吧。自己写一个吧importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassRegularExpressionTest{publicstaticvoidmain(S......
  • 浅谈java异常[Exception]
    评:一.异常的定义在《java编程思想》中这样定义异常:阻止当前方法或作用域继续执行的问题。虽然java中有异常处理机制,但是要明确一点,决不应该用"正常"的态度来看待异常。绝对一点说异常就是某种意义上的错误,就是问题,它可能会导致程序失败。之所以java要提出异常处理机制,就是要......
  • 商城系统比较(三款不错的java开源商城系统推荐)和其他推荐
    今天给大家分享三套github上优质的商城开源项目,排名不分先后。1、newbee-mall(新蜂商城)仓库地址:https://github.com/newbee-ltd/newbee-mall特点:springboot开发,主要针对pc端,代码设计非常简洁,没有过多的分层,非常适合初学者学习。 2、macrozheng/mall(没有中文名,不太好记)仓库地......
  • java的异常
    异常:程序中发生的不正常的情况成为异常(语法错误和逻辑错误不是异常)。异常分为两类:1.Error:java虚拟机无法解决的严重问题,程序会崩溃,如栈溢出(stackoverflowerror)、内存不足等2.Exception:由于编程错误或外在因素导致的一般性问题,可以使用正对行的代码进行处理,如......
  • JAVA动态代理内部实现
    评:一代理设计模式代理模式为目标对象提供一种代理以控制对实际对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。为了保持行为的一致性,代理类和实际委托类通常会实现相同的接口,所以在访问者看来两者没......
  • 一文吃透Java并发高频面试题
    内容摘自我的学习网站:topjavaer.cn分享50道Java并发高频面试题。线程池线程池:一个管理线程的池子。为什么平时都是使用线程池创建线程,直接new一个线程不好吗?嗯,手动创建线程有两个缺点不受控风险频繁创建开销大为什么不受控?系统资源有限,每个人针对不同业务都可以手动......
  • Ubuntu22.04 安装 java JDK
    0前言1下载jdk2.配置环境变量(只修改用户配置)参考0前言Linux一般使用openjdk,其主要由Oracle提供,部分源码不可见一般学习以jdk8为基础.以下教程为jdk8的Linux-Ubuntu的安装教程1下载jdkOracle网站:https://www.oracle.com/java/technologies/downloads/#java8下载后......
  • 2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不
    2023-06-04:你的音乐播放器里有N首不同的歌,在旅途中,你的旅伴想要听L首歌(不一定不同,即,允许歌曲重复,请你为她按如下规则创建一个播放列表,每首歌至少播放一次,一首歌只有在其他K首歌播放完之后才能再次播放。返回可以满足要求的播放列表的数量。由于答案可能非常大,请返回它......
  • 2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不
    2023-06-04:你的音乐播放器里有N首不同的歌,在旅途中,你的旅伴想要听L首歌(不一定不同,即,允许歌曲重复,请你为她按如下规则创建一个播放列表,每首歌至少播放一次,一首歌只有在其他K首歌播放完之后才能再次播放。返回可以满足要求的播放列表的数量。由于答案可能非常大,请返回它模10^9......
  • 必知必会:多线程
    1.线程的6种状态(1)New:初始状态,线程被创建,但是还没调用start方法。(2)Running:就绪状态和运行状态,统称为运行状态(3)Blocked:阻塞状态(4)Waiting:等待状态,需要等待其他线程做出特定的动作(通知或中断)。(5)Time-Waiting:超时等待状态,表示可以在指定的时间自行返回。(6)Terminated:终止状态,表示当前......