1.并发与并行
2.进程的概念
进入到内存中的执行的程序叫进程
3.线程的概念
线程:是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程(单线程程序)。一个 进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
4.线程的调度
- 分时调度
所有的线程轮流使用cpu的使用权,平均分配每个线程占用cpu的时间
- 抢占式调度
优先让优先级高的线程使用cpu,如果线程的优先级相同的,那么会随机选择一个线程执行(线程的随机性),java使用的就是抢占式调度
5.主线程(了解-扩展知识点)
执行main(主)方法的线程,叫主线程
package com.itheima.demo05mainThread;
/*
主线程(了解-扩展知识点)
执行main(主)方法的线程,叫主线程
*/
public class Dem01 {
public static void main(String[] args) {
Person p1 = new Person("小明");
p1.run();
/*
Exception in thread "main"
java.lang.ArithmeticException: / by zero
*/
System.out.println(0/0);
Person p2 = new Person("小红");
p2.run();
}
}
package com.itheima.demo05mainThread;
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void run(){
//打印20次姓名
for (int i = 1; i <= 20; i++) {
System.out.println(name+"\t"+i);
}
}
}
6.多线程程序创建的第一种方式:继承Thread类(重点)
package com.itheima.demo06Thread;
/*
多线程程序创建的第一种方式:继承Thread类(重点)
java.lang.Thread类:是一个描述线程的类
线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。
实现步骤:
1.创建一个类继承Thread类
2.在子类中重写Thread类中的run方法,设置线程任务(开启线程的目的:查杀病毒,清理垃圾,打印20次Hello)
3.创建Thread类的子类对象
4.调用继承自Thread类中的start方法,开启一个新的线程,执行run方法
---------------------------------------------------------------------------
void start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
1).启动start方法后,结果是两个线程并发地运行;
当前线程(主线程:执行main方法)和
另一个线程(开启的新线程:执行其 run 方法)。
2).多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
一个线程对象只能执行一次start方法
*/
public class Demo01Thread {
public static void main(String[] args) {
//3.创建Thread类的子类对象
MyThread mt = new MyThread();
//4.调用继承自Thread类中的start方法,开启一个新的线程,执行run方法
mt.start();
//主线程在开启新的线程之后,会继续执行main方法中的代码
for (int i = 1; i <= 20; i++) {
System.out.println("main==>"+i);
}
}
}
package com.itheima.demo06Thread;
//1.创建一个类继承Thread类
public class MyThread extends Thread{
//2.在子类中重写Thread类中的run方法,设置线程任务
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
System.out.println("run==>"+i);
}
}
}
程序的执行结果:随机性结果:
main==>1
main==>2
run==>1
main==>3
run==>2
main==>4
run==>3
main==>5
run==>4
main==>6
run==>5
main==>7
run==>6
main==>8
run==>7
main==>9
run==>8
main==>10
run==>9
main==>11
run==>10
main==>12
run==>11
main==>13
run==>12
main==>14
run==>13
main==>15
run==>14
main==>16
run==>15
run==>16
run==>17
run==>18
run==>19
run==>20
main==>17
main==>18
main==>19
main==>20
7.多线程随机性打印结果的原理(了解-扩展知识点)
8.获取线程的名称
package com.itheima.demo07getThreadName;
/*
获取线程的名称
线程是有名字的
主线程:main
新的线程:Thread-0,Thread-1,Thread-2
1.可以使用Thread类中的方法getName获取线程的名称
String getName() 返回该线程的名称。
2.可以使用Thread类中的[静态方法],先获取到当前正在执行的线程(Thread对象)
static Thread currentThread() 返回对当前正在执行的线程对象的引用。
在通过当前的线程Thread对象,在调用getName方法获取名称
*/
public class MyThread extends Thread{
@Override
public void run() {
//String name = getName();
//System.out.println(name);
//Thread t = Thread.currentThread();
//String name = t.getName();
//System.out.println(name);
//链式编程
System.out.println(Thread.currentThread().getName());
}
}
package com.itheima.demo07getThreadName;
public class Demo01GetThreadName {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
//多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
//mt.start();//IllegalThreadStateException:非常线程状态异常
new MyThread().start();
new MyThread().start();
new MyThread().start();
new MyThread().start();
//在main方法,可以主线程的名称
System.out.println(Thread.currentThread().getName());
}
}
9.Thread类中方法sleep(重点)
package com.itheima.demo08sleep;
/*
Thread类的静态方法:
static void sleep(long millis)
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),线程睡醒了继续执行
*/
public class Demo01Sleep {
public static void main(String[] args) {
System.out.println("让以下程序睡眠5秒钟之后在执行...");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("5秒钟到了,程序开始执行!");
}
}
package com.itheima.demo08sleep;
public class Demo02Sleep {
public static void main(String[] args) throws InterruptedException {
//秒表:一秒钟执行一次
/*for (int i = 1; i <=60 ; i++) {
System.out.println(i);
//睡眠1秒钟,在继续执行
Thread.sleep(1000);
}*/
for (int i = 60; i >=1 ; i--) {
System.out.println(i);
Thread.sleep(1000);
}
}
}
10.多线程程序创建的第二种方式:实现Runnable接口(重点)
package com.itheima.demo09Runnable;
/*
多线程程序创建的第二种方式:实现Runnable接口(重点)
java.lang.Runnable接口
Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。
类必须定义一个称为 run 的无参数方法。
java.lang.Thread类 implements Runnable接口
Thread类的构造法方法:
Thread(Runnable target) 传递Runnable接口的实现类对象
实现步骤:
1.创建一个实现类,实现Runnable接口
2.在实现类中重写Runnable接口中的run方法,设置线程任务
3.创建Runnable接口的实现类对象
4.创建Thread对象,构造方法中传递Runnable接口的实现类对象
5.调用Thread类中的start,开启新的线程,执行run方法
*/
public class Demo01Runnable {
public static void main(String[] args) {
//3.创建Runnable接口的实现类对象
RunnableImpl run = new RunnableImpl();
//4.创建Thread对象,构造方法中传递Runnable接口的实现类对象
Thread thread = new Thread(run);
//5.调用Thread类中的start,开启新的线程,执行run方法
thread.start();
//mian线程在开启新的线程之后,会继续执行main方法中的代码
for (int i = 1; i <= 20; i++) {
System.out.println(Thread.currentThread().getName()+"==>"+i);
}
}
}
package com.itheima.demo09Runnable;
//1.创建一个实现类,实现Runnable接口
public class RunnableImpl implements Runnable{
//2.在实现类中重写Runnable接口中的run方法,设置线程任务
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
System.out.println(Thread.currentThread().getName()+"==>"+i);
}
}
}
随机性的打印结果:
main==>1
main==>2
main==>3
main==>4
main==>5
main==>6
main==>7
main==>8
main==>9
main==>10
main==>11
main==>12
main==>13
main==>14
Thread-0==>1
main==>15
Thread-0==>2
main==>16
Thread-0==>3
main==>17
Thread-0==>4
Thread-0==>5
Thread-0==>6
main==>18
Thread-0==>7
main==>19
Thread-0==>8
main==>20
Thread-0==>9
Thread-0==>10
Thread-0==>11
Thread-0==>12
Thread-0==>13
Thread-0==>14
Thread-0==>15
Thread-0==>16
Thread-0==>17
Thread-0==>18
Thread-0==>19
Thread-0==>20
11.创建多线程程序两种方式的区别
创建多线程程序两种方式的区别
1.使用实现Runnable接口的方式创建多线程程序,可以避免单继承的局限性
a.类继承了Thread类,就不能在继承其他的类了
b.类实现了Runnable接口,还可以在继承其他的类
2.使用实现Runnable接口的方式创建多线程程序,可以把设置线程任务和开启线程进行了解耦(解除了耦合性,增强了扩展性)
a.类继承了Thread,在run方法中设置什么任务,创建子类对象就只能执行什么任务了(耦合性强)
b.类实现了Runnable接口目的:重写run方法设置线程任务
创建Thread类对象的目的:传递不同的Runnable接口的实现类对象(传递不同的任务),执行不同的任务
package com.itheima.demo10ThreadAndRunnale;
//a.类继承了Thread类,就不能在继承其他的类了
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("哈哈");
}
}
package com.itheima.demo10ThreadAndRunnale;
//b.类实现了Runnable接口,还可以在继承其他的类
public class RunnableImpl extends Person implements Runnable {
@Override
public void run() {
System.out.println("呵呵");
}
}
package com.itheima.demo10ThreadAndRunnale;
//b.类实现了Runnable接口,还可以在继承其他的类
public class RunnableImpl2 extends Person implements Runnable {
@Override
public void run() {
System.out.println("嘿嘿");
}
}
package com.itheima.demo10ThreadAndRunnale;
public class Demo01 {
public static void main(String[] args) {
MyThread mt = new MyThread();
//a.类继承了Thread,在run方法中设置什么任务,创建子类对象就只能执行什么任务了(耦合性强)
mt.start();//只能执行打印"哈哈"的任务
//创建Thread类对象的目的:传递不同的Runnable接口的实现类对象(传递不同的任务),执行不同的任务
//new Thread(new RunnableImpl()).start();//传递RunnableImpl对象,执行打印"呵呵"的任务
new Thread(new RunnableImpl2()).start();//传递RunnableImpl2对象,执行打印"嘿嘿"的任务
}
}
12.匿名内部类的方式实现多线程程序(重点)
package com.itheima.demo11Thread;
/*
匿名内部类的方式实现多线程程序(重点)
作用:简化代码,不用在定义子类|实现类了
把子类继承父类,重写父类中的方法,创建子类对象,合成一步完成
把实现类实现接口,重写接口中的方法,创建实现类对象,合成一步完成
格式:new 爹(亲爹==>父类,干爹==>接口)
new 父类|接口(){
重写父类|接口中的方法
};
记住:匿名内部类最终产生的是一个子类|实现类对象
*/
public class Demo01Thread {
public static void main(String[] args) {
//父类: Thread
//new MyThread().start();
new Thread(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}.start();
//接口: Runnable接口
//Runnable r = new RunnaleImpl();
//new Thread(r).start();
//多态 接口 = 匿名实现类对象
Runnable r = new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
new Thread(r).start();
//new Thread(new RunnaleImpl()).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
}
}
🎗经验分享
1. 代码
线程类
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("新线程执行了:" + i);
}
}
}
测试类
/*
测试类
*/
public class Demo01Test {
public static void main(String[] args) throws InterruptedException {
//创建线程
MyThread m = new MyThread();
//启动三次,执行三次线程任务
m.start();
m.start();
m.start();
}
}
2.出现的问题
3.问题的分析
线程创建之后,只能启动一次。
/*
测试类
*/
public class Demo01Test {
public static void main(String[] args) throws InterruptedException {
//创建线程
MyThread m = new MyThread();
m.start();
MyThread m2 = new MyThread();
m2.start();
MyThread m3 = new MyThread();
m3.start();
}
}