多线程

多线程

一 基本概念:程序,线程 ,进程

1. 程序:

​ 就是指为完成特定任务,用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象

2. 进程:

​ 就是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程,有他自身的产生,存在和消亡的过程——生命周期

ps:

就好像一首歌在手机中播放的过程就是一个进程运行的过程

  • 程序是静态的,进程是动态的
  • 进程作为资源分配的单位

3. 线程(多线程可能产生安全隐患)

  • 若一个进程在同一时间并发执行一个单位,那么他就叫多线程
    • 线程作为调度和执行的单位,每个线程都拥有独立的运行栈和程序计数器。

(就是在同一个进程之中,同时执行不同的步骤的过程,就是多线程的过程)

#特别注意
  1. 由于一个进程之中自有一个堆和方法区:那么就意味着一个进程里面的多个线程共同拥有一个堆和方法区
  2. ​ 但是他的运行栈和程序计数器(pc)他是独立的

4. 并行和并发

  • 并行: 多个CPU同时执行多个任务,比如:多个人同时做不同的事情。
  • 并发: 一个CPU采用时间片的法式执行多个程序:就是多个人去做一件事情

5.多线程的优点

​ 问题提出: 以单核cpu为例,只使用单个线程先后完成多个任务(调用多个方法),绝对会比多个线程来完成用的时间短,为何要使用多线程呢?

  1. 提高程序的呼应,对图形化界面共有意义,可增加用户的体验
  2. 提高计算机操作系统dcpu的利用率
  3. 改善程序结构,将既长且复杂的代码分为多个线程,独立运行,利于理解和修改

何时需要:

  1. 需要同时执行多个任务

  2. 程序实现一些需要等待的任务:如用户输入,读写操作,网络操作,搜索等

  3. 需要一些后台运行的程序时

    (就是有多个图片的时候,不断加载图片的时候你就要多线程去加载图片,要不然你会非常的卡顿)

二 线程的创建和使用(重点)

1. Thread类的常用方法:

  1. void start(); ——启动进程,并执行对象的run方法

  2. run(): ——线程在被调度时执行的操作

  3. String getName()——返回线程名称

  4. void setName(string name :)——设置线程名字

  5. static Thread currentThread()——返回当前线程,在Thread子类中就是this,返回用于主线程和Runnable实现类

  6. yield()——其实就是释放当前cpu的执行权,然后就可以交替执行了

  7. join()——在B中调用A的join方法,进程B就进入堵塞状态,只有B执行完后,A才可以继续执行 其实就是一个插队命令在线程

  8. stop()——强制结束命令(已过时)

  9. sleep(lang milltime);——强制堵塞

    package demo02;
    
    /**
    
    1. void start();  ——启动进程,并执行对象的run方法**
    
          2. **run(): ——线程在被调度时执行的操作**
    
             3. **String getName()——返回线程名称**
                4. **void setName(string name :)——设置线程名字**
                5. **static Thread currentThread()——返回当前线程,在Thread子类中就是this,返回用于主线程和Runnable实现类**
                   6.yield方法:
                   */
                   public class TheadMethodTest {
         
                   public static void main(String[] args) throws InterruptedException {
         
                   MyThead a1 = new MyThead("gjh");
                   MyThead T1 =  new MyThead();
                   // 4. **void setName(string name :)——设置线程名字**
                   T1.setName("线程一");
                   T1.start();
                   //方法二:通过有偿构造方法设置
                   a1.start();
                   //给主线程命名
                   Thread.currentThread().setName("主线程");
                   for (int i = 0; i <100 ; i++) {
         
                   if (i%20 == 0) {
         
                   System.out.println(Thread.currentThread().getName()+":"+i);
                   //6.yield()主动释放cpu资源
                   Thread.currentThread().yield();
    
             }
             if (i==20){
         
                 //分线程T1执行完毕之前不执行
                T1.join();
             }
                 }}
    }
    
     class MyThead  extends Thread{
         public MyThead(){
         }public MyThead(String name){
         super(name);}@Overridepublic void run() {
         for (int i = 0; i <100 ; i++) {
         if (i%10 == 0) {
         try {
         sleep(100);} catch (InterruptedException e) {
         
    ​                     e.printStackTrace();}
    ​                 System.out.println(Thread.currentThread().getName()+":"+i);//this.yield();}}}
     }
    

2.CPU调度策略

  1. 线程的优先级设置:
  • MAX_PRIORITY:10
  • MIN_PRIORITY:1
  • NORM_PRIORITY:5
  1. 涉及的方法:

    • getPriority() :返回线程优先级
    • setPriority(int newPriority) 改变线程的优先级
  2. 说明

    • 线程创建时继承父线程的优先级
    • 低优先级只是获得调度的概率低,并非一定是在高优先级线程之后才被调用的
  3. 如何设置当前线程的优先级

    getPriority()–获取当前线程的优先级

    setPriority()——设置当前进程的优先级

    —优先级高那么他就有可能高概率被先执行

3. 多继承的创建:

方法一:继承与Thread类
  1. 创建一个继承于thread类的子类

  2. 重写Thread类的ren()

  3. 创建Thread类的子类对象

  4. 通过此对象调用start()

    ​ ①启动当前进程

    ​ ②调用当前进程run方法

例子:

package demo01;
/*
 *         遍历100以内的偶数
 *  
 */

//1. 创建一个继承于thread类的子类
class MyThread extends Thread{
   
/*
2.  重写Thread类的run()方法——>将执行操作写在run里面去
*/
    @Override
    public void run() {
   
        for (int i = 0; i < 100; i++) {
   
            if (i%2==0){
   
                System.out.print(i+" ");
                if (i%20==0){
   
                    System.out.println("");
                }
            }
        }
    }
}
class ThreadTest {
   
    public static void main(String[] args) {
   
        //3. 创建Thread类的子类对象
        MyThread l1 = new MyThread();

        //调用他的start方法
        l1.start();
        //问题一:不可以直接使用run来调用相关进程
        //l1.run();
        
        
        //问题二:一个线程只能调度一次
        //l1.run();
        //正确做法
        MyThread l2 = new MyThread();
        l2.start();
        //下面的方法依旧实在主线程中执行的 
                for (int i = 0; i <100 ; i++) {
   
            if (i % 2 == 0) {
   
                System.out.print(i + " -------");
                if (i % 20 == 0) {
   
                    System.out.println("");
                }
            }
        }
    }
    }

}

所以可以看出他是多个进程一起执行的

练习:

package demo02;
 /**
创建两个分线程
1.遍历一百内的偶数
2.遍历一百以内的奇数
  @author 高嘉宏
  @date 2021-3-9
 */
public class ThreadDemo {
   
     public static void main(String[] args) {
   
         MyThread1 t1 = new MyThread1();
         MyThread2 t2 = new 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值