Java多线程详解
Java多线程详解
1、并发
指的是多个事件在同一时间段内发生(多个事件交替执行);
2、并行
指的是多个时间在同一时刻发生(多个事件同时执行)(CPU是多核的情况下才能并行);
1、程序
程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念;
2、进程
①是指一个内存中运行的应用程序,每个进程都有独立的内存空间,一个应用程序可以同时运行多个进程;
②进程也程序的一次执行过程,是系统运行程序的基本单位;
③系统运行一个程序即是进程的创建、运行到消亡的过程;
、线程
①线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程;
②一个进程可以有多个线程,这个应用程序可以称为多线程程序;
注意:
很多多线程是模拟出来的,真正的多线程指的是有多个CPU,即多核,如服务器;
一个CPU在一个时间点只能执行一个线程,但由于各线程之间切换的速度极快,所以模拟出来的多线程会令人感到有同时执行的错觉;
简言之:一个程序至少有一个进程,一个进程可以有多个线程;
1、分时调度
所有线程轮流获得CPU的使用权,平均分配每个线程占用CPU的时间;
2、抢占式调度
优先让优先级高的线程使用CPU,如果线程优先级相同那么或随机选一个(线程随机性),java使用的为抢占式调度;
1、主线程
执行主方法(main)的线程;
2、单线程程序
①程序只有一个线程;
②程序从main方法从上到下一次执行;
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调度了才执行;
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);
}
}
}
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的区别 = 使用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();
(了解,工作三五年之后变得重要!)
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接口的好处
可以定义返回值;
可以抛出异常;
1、Thread实现了Runnable接口
代码语言:javascript代码运行次数:0运行复制class Thread implements Runnable
底层原理就是静态代理模式,Runnable是一个多线程接口,只有一个run方法,Thread代理了这个run方法,并添加了一些其他功能;
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
上一篇:【Java设计模式】021
下一篇:Java异常详解
推荐阅读
留言与评论(共有 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 |