【多线程】线程的引入,创建线程的方式,设置线程名字、获取名字,线程优先级priority,加入休眠的方法,,后台线程,礼让线程,Join,中断线程,某电影院,共有100张票线程流程图,3售票窗口,

多线程

1.线程的引入

进程:
正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和资源。
线程:
是进程的单个顺序控制流,或者说就是一个单独执行的路径
一个进程如果只有一条执行路径,称之为单线程
一个进程如果有多条执行路径,称之为多线程
线程是包含在进程中。
举例:扫雷,360杀毒软件,百度网盘

了解三个关键词:
1、串行,指的是一个程序中所有的任务都是按照先后顺序执行的,在前一个任务还没有处理完的情况下,是不会进行处理下一个任务的
举例:理发店只有一个理发师,很多人去理发,先等前面的人理完发,再轮到后面的人。
2、并行,指的是将任务分给不同的处理器去处理,每一个处理器中再进行串行处理。
举例:火车站上有很多个窗口,多个窗口同时卖票,但是针对于一个窗口来说,一个人的一个人的去卖票
3、并发,实质上是一种现象,并发需要处理器的支持,比如在处理一个任务的时候操作系统可以进行调用再处理其他的任务,不论串行还是并行
都需要操作系统的支持并发。假设喝水是一个任务,每个火车站售票员,再售票的同时也能喝水,这就表示支持并发。比如:一个人在吃饭,吃着吃着电话来了,
他停止去吃饭然,去接电话,这就是并发。而这个人吗,没有停下吃饭而是一边打电话一边吃饭,这就叫做并行

JVM启动的时候是单线程还是多线程呢?
多线程:
main(主线程)
垃圾回收线程
所以在JVM启动的时候,最低要求要有两个线程存在,所以JVM启动的时候是多线程的。

2.创建线程的第一种方式:继承Thread类

    1、创建一个自定义类继承Thread类
    2、这个类要重写Thread类中的run方法
        为什么是run()方法呢?
        当线程启动之后,执行的代码逻辑仅是run()方法的代码逻辑
    3、根据这个类创建线程对象
    4、启动线程

面试题:调用start()与调用run()的区别
run()方法中仅仅是封装了被线程执行的代码,但是呢,直接调用run()与调用普通的方法方式没有任何区别
start()方法的调用,首先单独启动了一个线程,然后再由JVM去调用该线程类中的run()方法 // myThread1.start();

public class MyThreadDemo2 {
   
    public static void main(String[] args) {
   

        //每创建一个对象,相当于创建一个新的线程对象
//        MyThread1 myThread1 = new MyThread1();

        //启动线程
//        myThread1.run();
//        myThread1.run();
        //单纯的调用run方法仅仅表示的是一个对象调用普通的方法,所以这里依旧是单线程程序
        //要想看到多线程的效果,就必须换一种方式启动线程 start()


        //面试题:调用start()与调用run()的区别
        //run()方法中仅仅是封装了被线程执行的代码,但是呢,直接调用run()与调用普通的方法方式没有任何区别
        //start()方法的调用,首先单独启动了一个线程,然后再由JVM去调用该线程类中的run()方法
 //       myThread1.start();
  //当一个线程对象启动多次的时候,报错:
  //IllegalThreadStateException 非法的线程状态异常
//        myThread1.start();


        //模拟多线程环境
        //至少创建2个及两个以上的线程对象

        MyThread2 myThread1 = new MyThread2();
        MyThread2 myThread2 = new MyThread2();
        myThread1.start();
        myThread2.start();
        /**
         *      注意事项:
         *          1、启动线程调用的是start()方法
         *          2、线程的先后启动顺序,对结果没有影响
         */

    }
}

MyThread2类:

package com.shujia.wyh.day02.day24;

public class MyThread2 extends Thread{
   
    @Override
    public void run() {
   
        for (int i=0;i<100;i++){
   
            System.out.println(getName()+":"+i);
        }
    }
}

3.如何给线程设置名字呢? 如何获取线程的名字呢?

通过构造方法给线程起名字:
Thread(String name) 分配一个新的 Thread对象。

如何获取线程的名字呢?
public final String getName()返回此线程的名称

 public class MythreadDemo3 {
   
    public static void main(String[] args) {
   

        //创建线程对象
        //通过构造方法给线程起名字
  //由于我们要模拟多线程环境,所以创建线程的个数为2个或2个以上
      /*  MyThraed3 thraed1 = new MyThraed3("斗罗大陆");

        MyThraed3 thraed2 = new MyThraed3("斗破苍穹");
        thraed1.start();
        thraed2.start();*/



        //public final void setName(String name)将此线程
   //的名称更改为等于参数name 。

        MyThraed3 thraed1 = new MyThraed3();
        MyThraed3 thraed2= new MyThraed3();
        MyThraed3 thraed3 = new MyThraed3();

        thraed1.setName("一号厅");

        thraed2.setName("二号厅");

        thraed3.setName("三号厅");
        thraed1.start();
        thraed2.start();
        thraed3.start();


        //如何获取main方法所在的线程呢?
 //public static Thread currentThread()返回对当前正在执行
 //的线程对象的引用。
 System.out.println(Thread.currentThread().getName());
 //main



    }
}

MyThread3类:

public class MyThraed3 extends Thread {
   
    public MyThraed3() {
   
    }

    public MyThraed3(String name) {
   
        super(name);
    }

    @Override
    public void run() {
   
for (int i=0;i<=100;i++){
   
    System.out.println(getName()+":"+i);
    //getName()由于继承了Thread类所以可以通过此方法得到名字
}
    }
}

4.线程优先级priority

我们在前几个代码中都没有设置优先级,我们猜测一定会有一个默认的优先级。
默认的优先级是多少呢?5

获取线程优先级的方法:
public final int getPriority()返回此线程的优先级。
设置线程优先级的方法:
public final void setPriority(int newPriority)更改此线程的优先级。

public final static int MAX_PRIORITY = 10; 线程可以拥有的最大优先级。
public final static int MIN_PRIORITY = 1; 线程可以拥有的最小优先级。

总结:

1、线程的默认优先级是5
2、线程优先级的范围是1-10
3、线程优先级高仅仅表示的获取CPU时间片的机率会高一些,但是呢,并不是绝对会获取到

public class ThraedPriorityDemo4 {
   
    public static void main(String[] args) 

你可能感兴趣的:(Java基础,多线程,java)