线程的创建(Thread类和Runnable接口)
文章目录
前言
多媒体可以同时进行播放声音、播放视频、显示进度条的工作。这三个工作可以被看作线程。因为很多事情都是同时进行。而java为了在代码中创造出这种状态,同时让多个事情同时运行,于是有了线程的概念。当然,多个线程同时运行,这种思想就是耳熟能详的“并发”了。
一、线程是什么?
线程是程序中执行的一条路径,是进程中的一个实体。一个进程可以包含多个线程,每个线程负责执行不同的任务。线程之间可以并发执行,提高了程序的效率。线程共享进程的资源,包括内存、文件和其他系统资源,但每个线程都有自己的栈空间和寄存器。线程之间可以通过共享内存来通信。
总而言之:(进程可以看作一个独立运行的程序,一个线程是进程并发任务中的一个工作)
(1)进程是资源分配的最小单位,线程是最小的执行单位。
(2)一个进程可以有多个线程。
(3)线程共享进程资源。
线程有以下好处:
并发执行:线程可以实现多个任务同时进行,提高程序的执行效率。每个线程都可以独立执行不同的任务,可以同时处理多个请求或事件。
提高程序响应速度:通过将耗时的操作放在新的线程中执行,可以避免阻塞主线程,提高程序的响应速度。例如,在图形界面中,可以将网络请求、文件读写等耗时操作放在后台线程中执行,保持界面的流畅性。
资源共享:多个线程可以共享程序的资源,例如内存、文件、数据库等。这样可以减少资源的开销,提高资源的利用率。
方便的线程间通信:线程之间可以通过共享内存或消息传递等方式进行通信,方便数据的交换和共享。
多任务处理:线程可以将一个大型任务拆分成多个小任务,分配给多个线程并行处理,从而提高程序的整体执行效率。
二、线程的创建
Java中主要提供了两种方法实现线程,分别是继承 java.lang.Thread类 和实现 java.lang.Runnable接口。
1.Thread类
Thread类可以叫为线程类,这个类的实例化对象代表线程,开发者想要为程序添加一个线程,就需要创建Thread类实例。该Thread线程类在java.lang包下。
语法如下:
public class ThreadDemo extends Thread{
//...
}
Thread类的构造方法:
public Thread(); //创建一个新的线程对象
public Thread(String threadName); //创建一个名称为threadName的线程对象
以上的语法只是创造出了一个线程对象,这个线程具体做什么事,是否开始做这个事情都没有确定。目前只是创建了一个空壳子。
子类想运行线程,除了继承Thread类,还需要用到Thread类的两个方法,run()方法需要覆写,start()方法需要调用。
线程要实现什么样的功能,那么需要在run()方法中写什么样的代码。
run()方法覆写的语法格式:
public void run(){
//该线程想要实现的功能,代码写在此处
}
线程想要实现run()方法中的功能,就要创建自身的实例化对象,在main方法中调用start()方法。
start()方法直接被子类对象(ThreadDemo类)在main方法中调用即可。
public static void main(String[] args){
new ThreadDemo.start();
//ThreadDemo的run()方法启动
}
注:(1)若start()方法调用了一个已经启动的线程,系统将抛出IllegalThreadStateException异常。
(2)如果不在main主方法中调用start()方法,线程永远都不会启动,上述实例化的ThreadDemo对象只是一个实例,不是一个线程。
下面来展示如何使用Thread类来创建线程。
实操展示:创建自定义类ThreadDemo类,继承Thread类,然后覆写Thread类的run()方法,在main方法中实例化对象调用start()方法,运行该ThreadDemo线程。
public class ThreadDemo extends Thread{
int count = 10;
public void run(){
System.out.println("炸弹倒计时:");
while (count>0) {
System.out.println(count);
count--;
}
if (count==0) {
System.out.println("Bomb!!!");
}
}
public static void main(String[] args) {
new ThreadDemo().start();
}
}
运行结果:
如上图所示,这个单线程的任务是倒计时数数,我们编写的是线程的代码,但是一个单线程的代码,没有体现出并发的效果,当我们编写出多线程并发运行的代码时,线程的好处才会大大体现出来。在下面的Runnable接口中的实例,我们将展现多线程,当然继承Thread类也可以实现多线程,在这里就不重复描述了。
2.Runnable接口
大多数线程都是通过Thread类来创建,但java中父类只能继承一个。当开发过程中,想要继承其他的父类,还要实现线程的创建,很明显Thread类是不能满足的。这时候就有了Runnable接口供开发者使用,实现接口,覆写run()方法,main方法中创建Thread对象(引用本类对象),调用start()方法。
实现Runnable接口的语法如下:
pubLic class Thread extends Object implements{
//...
}
Thread类的两个构造方法:
new Thread(Runnable target);
//target:Runable实例对象
new Thread(Runnable target,String name);
Thread类的这两个构造方法将Runnable实例和Thread实例相关联了起来。
使用Runnable接口启动新的线程的步骤如下:
(1)建立Runnable对象。(本类实现了Runnable接口,本类实例化对象=Runnable对象)
(2)使用参数为Runnable对象的Thread类的构造方法,创建Thread类对象。
(3)调用start()方法启动线程。
实操展示:创建TestDemo类,继承JFrame类,实现Runnable接口,创建一个窗体,和一个加载图标,使用Runnable接口创建线程,使加载图标动起来。
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class TestDemo extends JFrame implements Runnable {
private JLabel jl = new JLabel(); // 图标
private int count = 0;
public TestDemo() {
setBounds(0, 0, 1960, 640);
try {
URL url = TestDemo.class.getResource("1.gif");
Icon icon = new ImageIcon(url);
jl.setIcon(icon);
} catch (NullPointerException e) {
System.out.println("没有该文件,请查询文件路径是否正确");
e.printStackTrace();
return;
}
jl.setHorizontalAlignment(SwingConstants.LEFT);
jl.setBounds(10, 10, 2000, 500);
jl.setOpaque(true);
Container container = getContentPane(); // 获取内容面板
container.setLayout(null);
container.add(jl); // 将JLabel添加到内容面板
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void run() {
count=10;
while(true){
jl.setBounds(count, 10, 2000, 500);
count+=10;
if(count>2000){
count=10;
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TestDemo testDemo = new TestDemo();
Thread thread = new Thread(testDemo);
thread.start();
}
}
运行结果:
如上图所示,加载图标在窗体中运行了起来,向右移动。
总结
以上就是线程的创建和使用,本文仅仅简单介绍了Thread类和Runnable接口的使用,而它们的使用,为我们开发程序提供了新的可能和思路,并发编程的思维尤为重要。有补充或者指正的内容,欢迎读者在评论区中留言。
原文地址:https://blog.csdn.net/weixin_74141222/article/details/140400186
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!