概述
你好我是辰兮,很高兴你能来阅读,本篇为Java基础之多线程的实现讲解,基础知识的讲解,相关的更多,面试知识已经提前整理好文章可以阅读学习,希望对初学者有帮助。
线程进程基础知识参考:
进程线程的面试问题小结线程面试常见问题参考:
Java常见多线程基础面试问题
文章目录
- 一、文章序言
- 二、继承Thread类
- 三、实现Runnable接口
- 四、两种实现方式的比较
- 五、调用start()与run()方法的区别
一、文章序言
创建线程的方式一致为Java面试常见基础问题,基础学习中我们常用前两种方式,下文带大家用代码案例进一步了解相关的知识。
常用第二种接口实现,因为实现接口的方式比继承类的方式更灵活,也能减少程序之间的耦合度。
二、继承Thread类
继承自Thread类,Thread类是所有线程类的父类,实现了对线程的抽取和封装
继承Thread类创建并启动多线程的步骤:
- ①.定义一个类,
继承自Thread类
,并重写该类的run方法,该run方法的方法体就代表了线程需要完成的任务,因此,run方法的方法体被称为线程执行体 - ②.
创建Thread子类的对象
,即创建了子线程 - ③.用线程
对象的start方法
来启动该线程
Demo先创建一个售票线程
package demo1;
public class SellTickets extends Thread {
//共享数据
static int count = 100;
@Override
public void run() {
//循环售票
while(count > 0) {
count--;
System.out.println(Thread.currentThread().getName() + "售出了一张票,剩余" + count);
}
}
}
测试类
import demo1.SellTickets;
public class TheadDemo {
public static void main(String[] args) {
//模拟四个售票员售票
SellTickets s1 = new SellTickets();
SellTickets s2 = new SellTickets();
SellTickets s3 = new SellTickets();
// System.out.println(s1.currentThread().getName()); //这个线程的名称是main
s1.start();
s2.start();
s3.start();
}
}
三、实现Runnable接口
实现Runnable接口创建并启动多线程的步骤:
- a.
定义一个Runnable接口的实现类
,并重写该接口中的run方法,该run方法的方法体同样是该线程的线程执行 体 - b.
创建Runnable实现类的实例
,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象 - c.
调用线程对象的start方法
来启动该线程
- 继续售票的案例
应该是继承implement接口,为了简洁我写一个里面了
package demo1;
public class SellTickets {
static int count = 100;
static Runnable r = new Runnable() {
@Override
public void run() {
while(count > 0) {
count--;
System.out.println(Thread.currentThread().getName() + "售出了 一张票,剩余" + count);
}
}
};
public static void main(String[] args) {
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
t1.start();
t2.start();
t3.start();
}
}
四、两种实现方式的比较
①实现Runnable接口的方式
a.线程类只是实现了Runnable接口,还可以继承其他类
【一个类在实现接口的同时还可以继承另外一个类】
b.可以多个线程共享同一个target对象
,所以非常适合多个线程来处理同一份资源的情况
c.弊端:编程稍微复杂,不直观,如果要访问当前线程,必须使用Thread.currentThread()
② 继承Thread类的方式
a.编写简单
,如果要访问当前线程,除了可以通过Thread.currentThread()方式之外,还可以使用 super关键字
b.弊端:因为线程类已经继承了Thread类,则不能再继承其他类【单继承】
实际上大多数的多线程应用都可以采用实现Runnable接口的方式来实现【推荐使用匿名内部类】java类是单知继承的
五、调用start()与run()方法的区别
Thread thread = new Thread();
thread.start();
① - start()方法会新建一个线程,并且让这个线程执行run()方法。
Thread thread = new Thread();
thread.run();
② - 调用run()也能正常执行。但是,却不能新建一个线程,而是在当前线程中调用run()方法,只是作为一个普通的方法调用。
我知道这样表达有点抽象,所有我截图了上述案例
建议:不要用run()来开启新线程,它只会在当前线程中,串行执行run()方法中的代码。
拓展一下源码的学习只截取了部分
public synchronized void start() {
private native void start0();
/**
* If this thread was constructed using a separate
* <code>Runnable</code> run object, then that
* <code>Runnable</code> object's <code>run</code> method is called;
* otherwise, this method does nothing and returns.
* <p>
* Subclasses of <code>Thread</code> should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
在start方法里调用了一次start0方法,这个方法是一个只声明未定义的方法,并且使用了native关键字进行定义native指的是调用本机的原生系统函数
。所以,调用start方法,会告诉JVM去分配本机系统的资源,才能实现多线程。
The best investment is to invest in yourself
2020.05.29 记录辰兮的第70篇博客
最后
以上就是等待钢笔为你收集整理的Java线程的实现方式详解(Java基础)的全部内容,希望文章能够帮你解决Java线程的实现方式详解(Java基础)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复