您的位置:首页 > 编程语言 > Java开发

Java多线程

2021-07-17 11:05 148 查看

Java多线程

程序、进程和线程

一、程序

  • 程序是存储在磁盘上, 包含可执行机器指令和数据的静态实体。 即进程或者任务是处于活动状态的计算机程序。

二、进程

  • 进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例,即运行中的程序。

  • 一个运行着的程序,可能有多个进程。进程在操作系统中执行特定的任务。

  • 程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

三、 线程

  • 线程就是程序的执行路线,即进程内部的控制序列,或者说是进程的子任务。
  • 线程,轻量级,不拥有自己独立的内存资源,共享进程的代码区、数据区、堆区(注意没有栈区)、环境变量和命令行参数、文件描述符、信号处理函数、当前目录、用户ID和组ID等资源。
  • 线程拥有自己独立的栈,因此也有自己独立的局部变量。
  • 一个进程可以同时拥有多个线程,即同时被系统调度的多条执行路线,但至少要有一个主线程。

总结

  • 线程就是独立的执行路径;
  • 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程;
  • main()称之为主线程,为系统的入口,用于执行整个程序;
  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与
  • 操作系统紧密相关的,先后顺序是不能认为的干预的。
  • 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
  • 线程会带来额外的开销,如cpu调度时间,并发控制开销。
  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

线程实现

继承Thread类

线程是程序中执行的线程。Java虚拟机允许应用程序同时运行多个执行线程。

每个线程都有优先权。 具有较高优先级的线程优先于具有较低优先级的线程执行。 每个线程可能也可能不会被标记为守护进程。 当在某个线程中运行的代码创建一个新的

Thread
对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护进程线程。

当Java虚拟机启动时,通常会有一个非守护进程线程(通常调用某个指定类的名为

main
的方法)。 Java虚拟机继续执行线程,直到发生以下任一情况:

  • 已调用类
    Runtime
    exit
    方法,并且安全管理器已允许执行退出操作。
  • 通过调用
    run
    方法返回或抛出超出
    run
    方法传播的异常,所有非守护程序线程的线程都已死亡。

创建线程方式一:继承Thread类,重写run()方法,调用start()开启线程

public class MyThread extends Thread{
@Override
public void run() {
//子线程方法
for (int i = 0; i < 20; i++) {
System.out.println("我是子线程" + i);
}
}

public static void main(String[] args) {
//开启子线程
new MyThread().start();

for (int i = 0; i < 20; i++) {
System.out.println("我是主线程" + i);
}
}
}

执行结果

可以发现,主线程和子线程是”同时“进行的。

Thread类实现了Runnable接口,内部通过静态代理调用了run()方法

实现Runnable接口

public class MyThread implements Runnable{
@Override
public void run() {
//子线程方法
for (int i = 0; i < 20; i++) {
System.out.println("我是子线程" + i);
}
}

public static void main(String[] args) {
//创建线程对象,代理线程
new Thread(new MyThread()).start();
for (int i = 0; i < 20; i++) {
System.out.println("我是主线程" + i);
}
}
}

使用方法基本和继承Thread类相同,执行结果也相似。

实现Callable接口

  • 实现Callable接口,需要返回值类型
  • 重写call方法,需要抛出异常
  • 创建目标对象
  • 创建执行服务: ExecutorService ser = Executors.newFixedThreadPool(1);
  • 提交执行: Future<Boolean> result1 = ser. submit(t1);
  • 获取结果: boolean r1 = result1.get()
  • 关闭服务: ser. shutdownNow();

示例代码

public class MyThread implements Callable<Boolean> {
@Override
public Boolean call() {
//子线程方法
System.out.println("执行了子线程");
return true;
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread t1 = new MyThread();
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(1);
//提交执行
Future<Boolean> result1 = ser.submit(t1);
//获取结果
boolean r1 = result1.get();
//关闭服务
ser. shutdownNow();
}
}

线程状态

线程同步

线程通信

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: