多线程(笔记)

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();
    }
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旭子在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值