当前位置: 首页 > article >正文

Java重点--多线程

目录

引入

一段代码:

内存图: 

Final

⭐并发(多个线程对同一个资源进行访问使用)

=======代码===部分======

一个输出日历的类

结果:

一个常用的Java:

构造器

什么是封装:


引入

线程的几种状态:新建--就绪--运行--死亡--阻塞--等待---睡眠

一段代码:

package 数据结构;

public class Text {
    public static void main(String[] mmm) {
        // 新建--就绪--运行--死亡--阻塞--等待---睡眠
        Thread x1=new Thread() {
            @Override  //重写run方法
            public void run() {
                for(;;) {
                    System.out.println("======");
                }
            }
        };
        Thread x2=new Thread() {
            @Override     //重写run方法
            public void run() {
                for(;;) {
                    System.out.println("#####");
                }
            }
        };
        x1.start();//进入就绪态,并不是立即执行(但是因为在操作系统中,和人交互的线程优先级最高,如键盘鼠标等输入输出的操作,所以达到了看似立即执行的效果)
              //操作系统能调度的任务只能是就绪态的
        x2.start();
        
        for(;;) {
            System.out.println("%%%%");
        }
        
    }
}
//多线程

内存图: 

  • 操作系统进行任务的统一调度,使CPU核心轮流执行(即核心也受操作系统调度);
  • 控制硬件必须通过驱动,而驱动必须受操作系统调度;
  • 线程优先级:如果因为高优先级的线程夺走了CPU,那么在高优先级线程执行结束后,会根据时间片记录的位置重新回到被剥夺线程进行调度运行。
  • 线程被分配的时间片是随机的,如果一个1ms就能执行结束的线程被分配了8ms时间片,那么剩余的7ms就会立即释放CPU,并分配给其他线程;如果一个8ms的线程被分配了1ms的时间片,那么时间片就会记录该线程调度的位置,等下次CPU得到时间片后,就会从上次执行剩余的开始位置7ms位置开始运行。
  • 像QQ、微信这种能一直进行,是因为里面有个死循环,没有被打破,所以会一直处于运行待机状态。

start()会将线程存在操作系统的就绪队列

多线程就是开了多个栈,并行(执行结束后,子线程会结束死亡,只剩下主线程存活):

堆中创建的对象,线程可以直接访问(因为进程是资源分配的最小单位-->而进程中的线程可以共享资源)

【补】线程是资源调度的最小单位,线程是进程中的基本单位(进程由线程组成)

⭐被final修饰的单元素变量不可以修改;引用类型不能更改指向(可以改变里面的值,不可以改变指向)

类似:线程调用公共资源时,子线程不能修改int等类型的单类型数据;int[]等类型的引用类型不能修改其指向(能修改其值);String字符串则不能被修改(因为字符串是不可变类型,想修改只能通过修改字符串常量池的指向,而且又因为String是引用类型,不能被修改指向,所以就不能修改了)

Final

final不修饰复杂的引用类型,因为它拦不住复杂引用类型属性的变化,所以通常final用来修饰基本类型和String类型。

【如下:final经常配合static配合使用,即静态常量】

 

======

线程创建完毕后就没有依赖关系了,所以Java中线程之间没有先后顺序,只有在同一线程内,才有顺序之分。

⭐并发(多个线程对同一个资源进行访问使用)

如下:

最终输出可能是?

 

结果是:0;

因为start()只是将x1,x2调为就绪态,又因为print是用户操作,所以很可能x1,x2还没来得及执行,就已经输出a[0]了。

解决(如下):

 

x1.join()功能就是要等x1执行完;同理加上x2.join(),就可以解决上面问题了

=======代码===部分======

一个输出日历的类

package 数据结构;

import java.time.DayOfWeek;
import java.time.LocalDate;

public class CalendarTest {
    public static void main(String[] args) {
        LocalDate date=LocalDate.now();
        int month=date.getMonthValue();
        int today=date.getDayOfMonth();
        
        date=date.minusDays(today-1);
        DayOfWeek weekday=date.getDayOfWeek();
        int value=weekday.getValue();
        
        System.out.println("Mon Tue Wed Thu Fri Sat Sun");
        for(int i=1;i<value;i++) {
            System.out.print("        ");
            while(date.getMonthValue()==month) {
                System.out.printf("%3d",date.getDayOfMonth());
                if(date.getDayOfMonth()==today) {
                    System.out.print("*");
                }else {
                    System.out.print(" ");
                }
                date=date.plusDays(1);
                if(date.getDayOfWeek().getValue()==1) {
                    System.out.println();
                }
            }
            if(date.getDayOfWeek().getValue()!=1) {
                System.out.println();
            }
        }
    }
}

结果:

 

一个常用的Java:

【一个class里面可以有多个类,但是只能有一个public类型的】

一个类:

package 数据结构;

import java.time.LocalDate;

public class Employee {
    private String name;
    private double salary;
    private LocalDate hireDay;
    //构造器
    public Employee(String n,double s,int year,int month,int day) {
        name=n;
        salary=s;
        hireDay=LocalDate.of(year, month, day);
    }
    //访问器*4(下面)
    public String getName() {
        return name;
    }
    public double getSalary() {
        return salary;
    }
    public LocalDate getHireDay() {
        return hireDay;
    }
    public void raiseSalary(double byPercent) {
        double raise=salary*byPercent/100;
        salary+=raise;
    }
}

【另一种表达方式:】

{类似于js里面的this方法,哪个对象调用,就表示谁}

Main函数

package 数据结构;

import javax.print.attribute.standard.MediaName;


public class EmployeeTest {
    public static void main(String[] args) {
        Employee[] staff=new Employee[3];
        
        staff[0]=new Employee("x1", 75000, 1989, 12, 22);
        staff[1]=new Employee("x3", 76000, 1939, 10, 12);
        staff[2]=new Employee("x5", 89000, 1984, 11, 2);
        
        for(Employee e:staff) {
            e.raiseSalary(5);
        }
        for(Employee e:staff) {
            System.out.println("name="+e.getName()+",salary="+e.getSalary()+",hireDay="+e.getHireDay());
        }    
    }
}

构造器

什么是封装:

只需要照着说明调用就好,不需要了解底层逻辑。

域就是属性,属性就是域(域.属性就是除却方法外的那些,属于大类的特性e.g .age,.name)

 


http://www.kler.cn/a/396779.html

相关文章:

  • 基于rk356x u-boot版本功能分析及编译相关(三)Makefile分析
  • vscode中执行git合并操作需要输入合并commit信息,打开的nano小型文本编辑器说明-
  • 数据结构-二叉树及其遍历
  • 黑盒测试案例设计方法的使用(1)
  • CSP-X2024山东小学组T2:消灭怪兽
  • CSS基础知识01
  • 241114.学习日志——[CSDIY] [CS]数据结构与算法 [00]
  • C++基础 抽象类 类模板 STL库 QT环境
  • OPEN - Linux手册页
  • apipost下载安装教程、脚本详细使用教程
  • 微积分第五版课后习题答案详解PDF电子版 赵树嫄
  • leetCode——二进制手表
  • 【数据结构 | C++】字符串关键字的散列映射
  • 算法——长度最小的子数组(leetcode209)
  • 新版Apache Tomcat ⽬目录文件讲解(笔记)
  • git 常用命令大全
  • datawhale11月组队学习 模型压缩技术3:2:4结构稀疏化BERT模型
  • 【时间之外】IT人求职和创业应知【34】-人和机器人,机器人更可靠
  • 常用List工具类(取交集、并集等等)
  • Python 数据可视化pilot
  • Spring Boot编程训练系统:用户体验设计与实现
  • 【C++】string模拟实现
  • SQL练习(2)
  • Linux篇(用户管理命令)
  • Python 桌面应用开发:使用 Tkinter 创建 GUI 应用程序
  • QT定时器