• 55.【Java 线程】


    1. 什么是进程?

    正在运行中的应用程序,通常称为进程。每个进程都有自己独立的地址空间(内存空间),每当用户启动一个进程时,操作系统就会为该进程分配一个独立的内存空间,让应用程序在这个独立的内存空间中运行。

    2.什么是线程?

    main函数是线程、Thread t=new Thread()。出来的是线程,正常的情况下的方法不是线程。).
    线程是一个轻量级的子进程,是最小的处理单元;是一个单独的执行路径。可以说:线程是进程的子集(部分)。

    3.线程特点:

    线程是独立的。如果在一个线程中发生异常,则不会影响其他线程。它使用共享内存区域。

    4.进程和线程的区别:

    1、容易创建新线程。但是,创建新进程需要重复父进程

    2线程可以控制同一进程的其他线程**。进程无法控制兄弟进程,只能控制其子进程。

    3、进程拥有自己的内存空间。线程使用进程的内存空间,且要和该进程的其他线程共享这个空间;而不是在进程中给每个线程单独划分一点空间。

    4、(同一进程中的)线程在共享内存空间中运行,而进程在不同的内存空间中运行。

    5、线程可以使用wait(),notify(),notifyAll()等方法直接与其他线程(同一进程)通信;而,进程需要使用“进程间通信”(IPC)来与操作系统中的其他进程通信。

    5.多任务和线程:

    在这里插入图片描述

    多任务是指在系统中同时运行多个程序,如果只有一个处理器只有一个进程的一个指令被执行,可以使这些程序进行交替执行,由于间隔的时间短,这些程序看上去好像在同时运行.
    如果将进程划分为线程,每个线程轮流占用处理器,可以减少并发时间.

    (一)、线程(Thread)

    1.线程的创建:

    为什么要创建线程?

    为了将进程划分为线程,要在程序中创建多个线程对象(java.lang.Thread)

    2.线程的构造方法:

    在这里插入图片描述

    3.线程的成员方法:

    在这里插入图片描述

    4.静态成员函数:(调用的时候要用类名)

    在这里插入图片描述

    5.线程的创建:

    在Java中,每个程序至少自动拥有一个主线程。如果需要使用其他线程,采用以下两种方式进行创建新的线程。
    第一种:

    继承(Thread)类,用它覆盖类方法中的run()方法.

    import java.sql.SQLOutput;
    import java.util.*;
    import java.awt.*;
    import java.lang.Math;
    public class hello extends Thread {
        public void run(){
            for(int i=0;i<10;i++){
                System.out.println(currentThread().getName()+i);
            }
        }
        public static void main(String []avgs) {
            System.out.println(activeCount());   //当前线程活跃数目
            hello h1=new hello();  //创建新线程
            hello h2=new hello();  //创建新线程
            h1.start();  //导入线程
            h2.start();  //导入线程
            //Thread.currentThread().getThreadGroup().list();
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    第二种:

    编写一个类,使它实现java.lang.Runnable接口,然后在Thread构造函数中使用它.

    import java.sql.SQLOutput;
    import java.util.*;
    import java.awt.*;
    import java.lang.Math;
    public class hello implements Runnable {
        public void run(){
            for(int i=0;i<10;i++){
                System.out.println(Thread.currentThread().getName()+" "+i);  //线程对象调用
            }
        }
        public static void main(String []avgs) {
            System.out.println(Thread.activeCount());   //当前线程活跃数目
            hello h1=new hello();  //接口对象
            Thread t1=new Thread(h1);  //把接口得对象传递给线程
            hello h2=new hello();  //接口对象
            Thread t2=new Thread(h2);//把接口得对象传递给线程
            t1.start();  //导入线程
            t2.start();  //导入线程
            //Thread.currentThread().getThreadGroup().list();   //得到调用线程的列表
            } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    (二)、线程的生命周期

    创建(new)—>就绪(start)—>运行中(调度)------->死亡(run()结束)
    阻塞:
    1.等待阻塞: 运行中 调用(wait())函数的时候,如果调用notify()或则notifyAll() 就解除当前的阻塞进入到 就绪阶段.
    2.互斥阻塞:运行中 调用synchronized()函数,试图获得某个对象的同步锁,如果该对象的同步锁已经被其他占用,则该线程被放入锁池中.
    3.其他阻塞: 运行中 调用sleep()函数,join()方法

    (三)、线程的优先级和调度:

    线程的优先级范围i是1~10,最低是1,最高是10,默认是5.
    获得优先级:

    getPriority()  //用于获得线程的优先级
    
    • 1

    设置优先级

    setPriority()  //用于设置优先级
    
    • 1

    1.线程的调度采用占先原则
    2.相同优先级的线程,有分时和独占两种调度方式.

    (四)、异常处理

    1.error类:

    包括了一些严重的。程序不能处理的系统错误,如同有内存不足,虚拟机错误、栈溢出等。这类错误主要由硬件问题引起的,与程序无关

    2.Exception类

    Exection类及其子类都是程序因考虑不周或不可控因素导致的错误,根据编译器是否对某类异常进行检查,Expection类分为非受检异常(运行异常)和受检异常(需要程序员处理)两种。

    3.异常处理步骤:

      					try{}
    
    • 1

    可能出现的异常语句块,可能有错误,也可能没有错误。当try子句中的某个语句发生异常后,产生异常对象,终止当前正在执行的语句,后面的语句将不再执行,然后抛出异常对象

      					catch{}
    
    • 1

    根据try{}抛出的异常对象,那么catch进行从上倒下一直捕捉异常对象,进行一直捕捉,直到找到为止

      					finnaly{}
    
    • 1

    无论是否异常,finnaly子句依然正常执行

    try{
    	
    }
    catch(异常类型1, 异常对象){
    		//处理类型1  (拆弹专家1)
    }
    catch(异常类型2, 异常对象){
    		//处理类型2   (拆弹专家2)
    }
    finally{
      无论出现异常都要抛出
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.举列子:

    错误信息:
    在这里插入图片描述
    捕捉错误:
    在这里插入图片描述
    手动修改错误:

    在这里插入图片描述

    (五)、漫天星辰

    import java.awt.*;
    import java.util.Random;
    
    public class panel extends Panel implements Runnable {
        int x=10;
        int y=10;
        int size=30;
        int m=500;
        int n=350;
        int k=650;
        int s=200;
        int f=200;
        public void paint(Graphics g) {
            //绘画云朵
            g.setColor(Color.LIGHT_GRAY);
            g.fillOval(m,250,300,150);
            g.fillOval(n,300,300,100);
            g.fillOval(k,300,300,100);
            //绘画月亮
            Color c = new Color(255, 255, 0);
            g.setColor(c);
            g.fillOval(200, 200, 100, 100);
            Color c1 = new Color(0, 0, 0);
            g.setColor(c1);
            //绘制半月
            g.fillArc(s, f, 100, 100, 0, 360);
            //绘画星星
            Color c2 = new Color(255, 192, 203);
            g.setColor(c2);
            Font f = new Font("黑体", Font.BOLD, size);
            g.setFont(f);
            int i=0;
            Random r=new Random();
            while(i++<300){
                x=r.nextInt(1980)+1;
                y=r.nextInt(1024)+1;
                g.drawString("*", x, y);}
        }
        public void run(){  //覆盖线程的操作
            while(true){
                if(n>=1980){   //云朵
                    n=350;   //左
                    m=500;    //中
                    k=650;    //右
                }
                if(f>310){   //半月
                    s=200;
                    f=200;
                }
                f++;
                s++;
                x++;
                y++;
                m++;
                k++;
                n++;
                try {
                    Thread.sleep(30);
                }catch (Exception e){
                    e.printStackTrace();
                }repaint();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    主方法:

    import java.sql.SQLOutput;
    import java.util.*;
    import java.awt.*;
    import java.lang.Math;
    public class hello  {
        public static void main(String []avgs) {
            Frame f=new Frame();
            f.setTitle("宝马");
            f.setBackground(Color.BLACK);
            f.setSize(800,800);
            panel p=new panel();
            f.add(p);
            Thread t=new Thread(p);  //添加线程
            t.start();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
            System.out.println(Thread.activeCount());   //当前线程活跃数目
            //Thread.currentThread().getThreadGroup().list();   //得到调用线程的列表
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    注意:我们在使用Thread 类的sleep()方法的时候,我们要对其进行异常处理操作,否则会报错的.

    (六)、提词器

    方法类:

    import java.awt.*;
    import java.util.Random;
    
    public class panel extends Panel implements Runnable {
        int x=100;
        public void run(){
           while (true){
            x=x+10;
            if(x>1920){
                x=100;
            }
            try {
                Thread.sleep(30);
            }catch (Exception e){
                e.printStackTrace();
            }repaint();
           }
        }
        public void paint(Graphics g) {
            Font f=new Font("黑体",Font.BOLD ,80);
            Color c=new Color(225,215,30);
            g.setColor(c);
            g.setFont(f);
            g.drawString("你",x,250);
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    主类:

    import java.sql.SQLOutput;
    import java.util.*;
    import java.awt.*;
    import java.lang.Math;
    public class hello  {
        public static void main(String []avgs) {
            Frame f=new Frame();
            f.setTitle("宝马");
            f.setBackground(Color.BLACK);
            f.setSize(1920,1080);
            panel p=new panel();
            f.add(p);
            Thread t=new Thread(p);
            t.start();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
            System.out.println(Thread.activeCount());   //当前线程活跃数目
            //Thread.currentThread().getThreadGroup().list();   //得到调用线程的列表
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    (七)、回弹的小球

    在这里插入图片描述

    类方法

    import javax.swing.*;
    import java.awt.*;
    import java.util.Random;
    
    public class panel extends Panel implements Runnable {
        int x=100;
        int y=100;
        int att=0;
        public void run(){
         while (true){
            //设置四个姿态:
            //右墙
            if(att==0){
                x++;
                y++;
            }
            //下强
            if(att==1){
                x--;
                y++;
            }if(att==2){//左墙
                x--;
                y--;
            }if(att==3){//上强
                x++;
                y--;
            }
            if(x>733){
                if(att==0){att=1;}
                else{att=2;}
            }
            if(y>711){回弹
                if(att==1){att=2;
                }else{att=3;}
            }
            if(x<0){
                if(att==2){
                    att=3;
                }else{
                    att=0;
                }
            }
            if(y<0){
                if(att==3){att=0;}
                else{att=1;}
            }
            try {
                Thread.sleep(1);
            }catch (Exception e){
                e.printStackTrace();
            }repaint();
        }}
        public void paint(Graphics g) {
            Color c=new Color(255,0,255);
            g.setColor(c);
            g.fillOval(x,y,50,50);
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    类方法:

    import java.sql.SQLOutput;
    import java.util.*;
    import java.awt.*;
    import java.lang.Math;
    public class hello  {
        public static void main(String []avgs) {
            Frame f=new Frame();
            f.setTitle("宝马");
            f.setBackground(Color.BLACK);
            f.setSize(800,800);
            panel p=new panel();
            f.add(p);
            Thread t=new Thread(p);
            t.start();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    (八)满天星辰(垂直降落版本)

    基本思路:如果要垂直降落的话,我们需要借助一个载体来帮我们储存乱序的300颗星星,首先我们呢可以想到数组的作用。数组可以帮我们用来储存元素的一系列的操作。首先我们要分析这个数组要建立在paint方法的外面因为如果放在里面,在线程的调用的同时我们的数组也会重新更新。我们的而目的是不让数组更新,所以数组必须在类外进行初始化。初始化的时候我们得想到构造函数,利用构造函数进行对数组得第一个300元素进行随机分配。然后在run函数里面对初始化得数组进行高度++程序,从而到达垂直降落的效果。
    类方法:

    import javax.swing.*;
    import java.awt.*;
    import java.util.Random;
    public class panel extends Panel implements Runnable  {
    
        int []m=new int[300];
        int []n=new int[300];
        public panel(){   //利用构造函数进行初始化前300
    
            for(int i=0;i<300;i++){
                Random r=new Random();
                int m1=r.nextInt(1920)+1;
                int n1=r.nextInt(1080)+1;
                m[i]=m1;n[i]=n1;
            }
        }
        public void run(){
            while(true){
                for(int i=0;i<300;i++) {
                    n[i]++;
                    if(n[i]==1080){
                        n[i]=0;
                    }
                }
                try {
                    Thread.sleep(10);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }repaint();
            }
        }
        public void paint(Graphics g){
                    Font f1 = new Font("黑体", Font.BOLD, 30);
                    Random r = new Random();
                    int m1=r.nextInt(255)+1;
                    int m2=r.nextInt(255)+1;
                    int m3=r.nextInt(255)+1;
                    g.setFont(f1);
                    Color c = new Color(m1, m2, m3);
                    g.setColor(c);
                    for (int i=0;i<300;i++) {   //绘制300个星星
                    g.drawString("*", m[i], n[i]);
                }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    主方法:

    import java.sql.SQLOutput;
    import java.util.*;
    import java.awt.*;
    import java.lang.Math;
    public class hello {
        public static void main(String[] avgs) {
        Frame f=new Frame("小球的撞击效果示范图");
        f.setSize(1920,1080);
        f.setBackground(Color.black);
        f.setLocationRelativeTo(null);
        panel p=new panel();
        f.add(p);
        Thread t=new Thread(p);
        t.start();
        f.setVisible(true);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

  • 相关阅读:
    密西根大学张阳教授受聘中国上海交通大学客座教授(图)
    计算机毕业设计python毕设项目之django本地健康宝微信小程序
    JAVA数据类型详解
    Git的安装配置及使用(超详细!!!)
    从零开始的深度学习之旅(1)
    Redis篇---第十一篇
    Java并发操作之synchronized互斥锁总结
    Vue项目实战——【基于 Vue3.x + Vant UI】实现一个多功能记账本(开发导航栏及公共部分)
    SpringBoot默认Json框架Jackson解析-基础篇
    Web知识点
  • 原文地址:https://blog.csdn.net/qq_69683957/article/details/126777697