您现在的位置是:首页 > 编程 > 

Java多线程详解

2025-07-29 10:27:34
Java多线程详解 一、并发与并行1、并发指的是多个事件在同一时间段内发生(多个事件交替执行);2、并行指的是多个时间在同一时刻发生(多个事件同时执行)(CPU是多核的情况下才能并行);二、程序、线程与进程1、程序程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念;2、进程①是指一个内存中运行的应用程序,每个进程都有独立的内存空间,一个应用程序可以同时运行多个进程;②进程也程序

Java多线程详解

一、并发与并行

1、并发

指的是多个事件在同一时间段内发生(多个事件交替执行);

2、并行

指的是多个时间在同一时刻发生(多个事件同时执行)(CPU是多核的情况下才能并行);

二、程序、线程与进程

1、程序

程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念;

2、进程

①是指一个内存中运行的应用程序,每个进程都有独立的内存空间,一个应用程序可以同时运行多个进程;

②进程也程序的一次执行过程,是系统运行程序的基本单位;

③系统运行一个程序即是进程的创建、运行到消亡的过程;

、线程

线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程;

②一个进程可以有多个线程,这个应用程序可以称为多线程程序;

注意:

很多多线程是模拟出来的,真正的多线程指的是有多个CPU,即多核,如服务器;

一个CPU在一个时间点只能执行一个线程,但由于各线程之间切换的速度极快,所以模拟出来的多线程会令人感到有同时执行的错觉;

简言之:一个程序至少有一个进程,一个进程可以有多个线程;

三、线程调度

1、分时调度

所有线程轮流获得CPU的使用权,平均分配每个线程占用CPU的时间;

2、抢占式调度

优先让优先级高的线程使用CPU,如果线程优先级相同那么或随机选一个(线程随机性),java使用的为抢占式调度;

四、主线程

1、主线程

执行主方法(main)的线程;

2、单线程程序

①程序只有一个线程;

②程序从main方法从上到下一次执行;

五、创建多线程程序的第一种方法(继承Thread类)

1、创建多线程程序

Thread类是描述多线程的类,要想常见多线程类就必须继承Thread类;

2、实现步骤

①创建Thread类的子类;

②重写Thread类中的run方法,设置线程任务(开启线程要做什么);

③创建Thread类的子类对象;

④调用Thread类中的start方法,开启新线程(调用start方法),执行run方法;

、start方法

①start方法的调用结果是两个线程并发地运行——当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法);

②多次启动一个线程是非法的,特别是当线程已经结束执行后,不能再重新启动;

③如果不调用start方法,而是调用run方法,就意味着不是开启新线程,只是调用一个类的普通方法,都在主线程执行;

4、注意

java程序属于抢占式调度,优先级高的线程优先执行,同一优先级的线程随机执行;

5、代码示例

自定义的线程类:
代码语言:javascript代码运行次数:0运行复制
package ;
//定义一个类继承Thread类
public class MyThread extends Thread {
    //重写Thread类的run方法,做要做的事情
    @Override
    public void run() {
        super.run();
        //输出run(0-9)
        for(int i=0; i<10; i++){
            println("run"+i);
        }
    }
}
Test测试类:
代码语言:javascript代码运行次数:0运行复制
package ;

public class Test {
    public static void main(String[] args) {
        //实例化一个自定义线程的对象
        MyThread myThread = new MyThread();
        //调用start方法,会自动执行run方法,开启一个新的线程
        myThread.start();//此处若写run方法,则执行run方法内容,并未开启新线程
        //在主方法中也输出main(0-9)
        for(int i=0; i<10; i++){
            println("main"+i);
        }
    }
}
执行结果(交替执行):
代码语言:javascript代码运行次数:0运行复制
main0
run0
main1
run1
main2
run2
main
run
main4
main5
main6
main7
main8
main9
run4
run5
run6
run7
run8
run9
六、多线程原理

1、随机打印

2、内存图解

、执行时机

开启子线程之后,子线程并不一定是立即执行,而是要看CPU是如何调度的,CPU调度了才执行;

七、Thread类的常用方法

1、获取线程名称

方法一:使用getame方法

自定义的线程类:

代码语言:javascript代码运行次数:0运行复制
package ;
//定义一个类继承Thread类
public class MyThread extends Thread {
    //重写Thread类的run方法,做要做的事情
    @Override
    public void run() {
        super.run();
        println(getame());
    }
}

Test测试类:

代码语言:javascript代码运行次数:0运行复制
package ;

public class Test {
    public static void main(String[] args) {
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
    }
}

运行结果:

代码语言:javascript代码运行次数:0运行复制
Thread-1
Thread-2
Thread-0
方法二:

自定义的线程类:

代码语言:javascript代码运行次数:0运行复制
package ;
//定义一个类继承Thread类
public class MyThread extends Thread {
    //重写Thread类的run方法,做要做的事情
    @Override
    public void run() {
        super.run();
        println(());
        //也可以这么写().getame();(链式编程)
        //输出的结果与方法一相同
    }
}

Test测试类:

代码语言:javascript代码运行次数:0运行复制
package ;

public class Test {
    public static void main(String[] args) {
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
    }
}

运行结果:

代码语言:javascript代码运行次数:0运行复制
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Thread[Thread-2,5,main]

2、设置线程名称(了解)

自定义的线程类:

代码语言:javascript代码运行次数:0运行复制
package ;
//定义一个类继承Thread类
public class MyThread extends Thread {
    public MyThread() {
        super();
    }
    //为线程设置名字的第二种方法
    public MyThread(String name) {
        super(name);
    }
    //重写Thread类的run方法,做要做的事情
    @Override
    public void run() {
        super.run();
        println(().getame());
    }
}

Test测试类:

代码语言:javascript代码运行次数:0运行复制
package ;

public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        //为线程设置名字的第一种方法
        myThread.setame("小明线程");
        myThread.start();//小明线程
        new MyThread("小李线程").start();
    }
}

运行结果:

代码语言:javascript代码运行次数:0运行复制
小明线程
小李线程

、sleep

作用:

使正在执行的线程,暂停特定的毫秒;

代码示例:

代码语言:javascript代码运行次数:0运行复制
package ;

public class TestSleep {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 61; i++) {
            println(i);
            //线程暂时1秒
            Thread.sleep(1000);
        }
    }
}
八、创建多线程程序的第二种方法(实现Runnable接口)

2019.9.21.10:19补充:

如果多线程类extends了另一个类,那就不能再extends第一种方法的Thread类了,所以可以通过实现Runnable接口实现多线程;

1、实现步骤

①创建Runable的实现类;

②该实现类重写run方法;

③创建实现类对象;

④new Thread(多线程实现类对象).start();

2、代码示例

RunnableImpl:
代码语言:javascript代码运行次数:0运行复制
package ;

public class RunnableImpl implements Runnable {
    @Override
    public void run() {
        println("Runnable接口实现类的run方法");
    }
}
Test测试类:
代码语言:javascript代码运行次数:0运行复制
package ;

public class RunnableImplTest {
    public static void main(String[] args) {
        RunnableImpl runnable = new RunnableImpl();
        new Thread(runnable).start();
    }
}
运行结果:
代码语言:javascript代码运行次数:0运行复制
Runnable接口实现类的run方法
九、Thread和Runnable的区别

Thread和Runnable的区别 = 使用Runnable接口的好处:

①避免了单继承的局限性——一个类继承了Thread就不能继承其他类,但若使用Runnable接口实现多线程则不仅就可以继承其他类,也可以继承其他接口;

②增强了程序的扩展性,降低了程序的耦合性(解耦)

——实现Runnable接口的方式,把设置线程任务和开启线程进行了分离(解耦);

——实现Runnable重写run方法用来设置线程的任务;

——创建Thread类用来开启线程;

十、匿名内部类方式实现线程的创建

1、继承Thread类的方式

代码语言:javascript代码运行次数:0运行复制
        //继承Thread类的方式
        new Thread(){
            @Override
            public void run() {
                super.run();
                println("继承Thread类的方式");
            }
        }.start();

2、实现Runnable接口的方式

代码语言:javascript代码运行次数:0运行复制
        //实现Runnable接口的方式
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                println("实现Runnable接口的方式");
            }
        };
        new Thread(runnable).start();
十一、创建多线程程序的第三种方法(实现Callable接口)

(了解,工作三五年之后变得重要!)

1、实现步骤

①实现Callable接口,需要返回值类型;

②重写call方法,需要抛出异常;

③创建目标对象;

④创建执行服务;

⑤提交执行;

⑥获取结果;

⑦关闭服务

2、代码实现

代码语言:javascript代码运行次数:0运行复制
package com.;

import java.*;

public class Dog implements Callable<Boolean> {
    @Override
    public Boolean call(){
        println("开始数狗:");
        for (int i = 0; i < 20; i++) {
            println("开始数狗,第" + i + "条狗!");
        }
        return true;
    }

    //主线程
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建执行服务
        ExecutorService service = (1);//线程池大小
        //提交执行
        Future<Boolean> result = service.submit(new Dog());
        //获取结果
        Boolean aBoolean = result.get();
        //关闭服务
        service.shutdownow();
        //打印结果
        println(aBoolean);
    }
}

、运行结果

代码语言:javascript代码运行次数:0运行复制
开始数狗:
开始数狗,第0条狗!
开始数狗,第1条狗!
开始数狗,第2条狗!
开始数狗,第条狗!
开始数狗,第4条狗!
开始数狗,第5条狗!
开始数狗,第6条狗!
开始数狗,第7条狗!
开始数狗,第8条狗!
开始数狗,第9条狗!
开始数狗,第10条狗!
开始数狗,第11条狗!
开始数狗,第12条狗!
开始数狗,第1条狗!
开始数狗,第14条狗!
开始数狗,第15条狗!
开始数狗,第16条狗!
开始数狗,第17条狗!
开始数狗,第18条狗!
开始数狗,第19条狗!
true

4、实现Callable接口的好处

可以定义返回值;

可以抛出异常;

十二、Thread底层原理——静态代理模式

1、Thread实现了Runnable接口

代码语言:javascript代码运行次数:0运行复制
class Thread implements Runnable

底层原理就是静态代理模式,Runnable是一个多线程接口,只有一个run方法,Thread代理了这个run方法,并添加了一些其他功能;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent 删除java程序多线程接口线程

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1200506.html

相关标签:无
上传时间: 2025-07-23 19:09:13
留言与评论(共有 14 条评论)
本站网友 上海网球
24分钟前 发表
Thread底层原理——静态代理模式1
本站网友 新浪视频下载软件
8分钟前 发表
Thread和Runnable的区别Thread和Runnable的区别 = 使用Runnable接口的好处:①避免了单继承的局限性——一个类继承了Thread就不能继承其他类
本站网友 alarmmanager
20分钟前 发表
第16条狗! 开始数狗
本站网友 国际雕塑公园
9分钟前 发表
继承Thread类的方式代码语言:javascript代码运行次数:0运行复制 //继承Thread类的方式 new Thread(){ @Override public void run() { super.run(); println("继承Thread类的方式"); } }.start();2
本站网友 刘伟东
5分钟前 发表
那就不能再extends第一种方法的Thread类了
本站网友 mtv下载软件
7分钟前 发表
工作三五年之后变得重要!)1
本站网友 石家庄教育培训
24分钟前 发表
实现Callable接口的好处可以定义返回值;可以抛出异常;十二
本站网友 四川其亚铝业集团有限公司
9分钟前 发表
第2条狗! 开始数狗
本站网友 新湖庐山国际
17分钟前 发表
做要做的事情 @Override public void run() { super.run(); println(getame()); } }Test测试类:代码语言:javascript代码运行次数:0运行复制package ; public class Test { public static void main(String[] args) { new MyThread().start(); new MyThread().start(); new MyThread().start(); } }运行结果:代码语言:javascript代码运行次数:0运行复制Thread-1 Thread-2 Thread-0方法二:自定义的线程类:代码语言:javascript代码运行次数:0运行复制package ; //定义一个类继承Thread类 public class MyThread extends Thread { //重写Thread类的run方法
本站网友 三岁宝宝身高体重标准
3分钟前 发表
匿名内部类方式实现线程的创建1
本站网友 blueair
21分钟前 发表
如服务器;一个CPU在一个时间点只能执行一个线程
本站网友 els
13分钟前 发表
第12条狗! 开始数狗
本站网友 heyjude
3分钟前 发表
原始发表:2025-01-06