Java中的多线程编程

简介: Java中的多线程编程

上节课内容回顾

进程, 进程调度, PCB结构,进程的虚拟空间地址,进程间的通信

进程和线程之间的区别和联系:

  1. 进程包含线程!一个进程里面可以有一个线程也可以有多个线程
  2. 进程和线程都能解决并发编程问题的场景,但是进程在频繁创建和销毁中,开销更高,线程开销更低(线程比进程更轻量级)
  3. 进程是系统分配资源(内存,文件资源…)基本单位,线程是系统调度执行的基本单位(CPU)
  4. 进程之间是相互独立的,各自有各自的虚拟空间地址.同一个进程的内部的多个线程之间共用一个内存空间以及文件资源.一个进程挂了其他进程一般都没事,但是一个线程挂了可能把整个进程搞崩

多线程仍然是最主流最常见的一种并发编程的方式

Java中如何进行多线程编程;

在Java标准库中,就提供了一个Thread类来表示操作线程

Thread可以视为Java标准库提供的API

创建好的Thread实例,其实和操作系统的线程是一一对应的关系,操作系统提供了一组关于线程的API(C语言风格)Java对于这组API进一步封装,就成了Thread类

Thread类的基本用法

第一种

通过Thread类创建线程,写法有多种,其中最简单的就是创建子类继承Thread,并且重写run方法

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("hello thread!");
    }
}
public class Main {
    public static void main(String[] args) {
        Thread thread = new MyThread();
        thread.start();
    }
}

run描述了每个线程内部要执行那些代码,每个线程都是并发执行的(各自执行各自的代码),因此就需要告诉这个线程你要执行什么代码

start需要调用这个start方法,才是真正的在系统上创建了线程,才是真正的执行上面的run操作,在调佣出start方法之前,系统是没有创建出线程的

线程之间是并发执行的,如果一个循环中不加任何的限制,这个循环转的速度非常快,导致打印的东西太多了,根本看不过来,就可以加上一个sleep操作,来强制让这个线程休眠一段时间

在一个进程中至少有一个线程,在一个Java进程中也是至少有一个调用main方法的线程,自己创建的线程和自动创建的main线程就是并发执行的关系(宏观看起来是同时执行)

使用场景:

class MyThread extends Thread {
    @Override
    public void run() {
        while(true) {
            System.out.println("hello thread!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Thread thread = new MyThread();
        thread.start();
        while(true) {
            System.out.println("hello main!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

现在两个线程,都是先打印一条就休眠1s,当1s时间到了之后,系统先唤醒谁那?(看起来这个顺序不是完全确定的)随机的,对于操作系统来说,内部对于线程之间的调度顺序,在宏观上认为是随机的(抢占式的)

第二种

创建一个类,实现Runable接口,再创建Runable实例传给Thread实例

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("hello thread!");
    }
}
public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }
}

第三种

就是上面俩种写法的翻版,使用了匿名内部类

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("hello thread!");
            }
        };
        thread.start();
    }
}

创建了一个匿名内部类,继承自Thread类,同时重写run方法,同时new这个匿名内部类的实例

第四种

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello thread!");
            }
        });
        thread.start();
    }
}

new Runable针对这个创建的匿名内部类,同时new出的Runable实例传给Thread 的构造方法

通常认为Runable这种写法更好一点,能够能够做到让线程和线程执行的任务更好的解耦,写代码一般希望高内聚,低耦合

第五种

相当于第四种写法的延伸,使用lambda表达式,是使用了lambda代替了Runable而已

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("hello thread!");
        });
        thread.start();
    }
}

以上五种写法都很常见大家都应该掌握


相关文章
|
2天前
|
缓存 负载均衡 安全
|
1天前
|
设计模式 算法 安全
Java编程中的设计模式:提升代码的可维护性和扩展性
【8月更文挑战第19天】在软件开发的世界里,设计模式是解决常见问题的一种优雅方式。本文将深入探讨Java编程语言中常用的几种设计模式,并解释如何通过这些模式来提高代码的可维护性和扩展性。文章不涉及具体的代码实现,而是侧重于理论和实践相结合的方式,为读者提供一种思考和改善现有项目的新视角。
|
1天前
|
安全 Java 测试技术
深入探讨Java安全编程的最佳实践,帮助开发者保障应用的安全性
在网络安全日益重要的今天,确保Java应用的安全性成为了开发者必须面对的课题。本文介绍Java安全编程的最佳实践,包括利用FindBugs等工具进行代码审查、严格验证用户输入以防攻击、运用输出编码避免XSS等漏洞、实施访问控制确保授权访问、采用加密技术保护敏感数据等。此外,还强调了使用最新Java版本、遵循最小权限原则及定期安全测试的重要性。通过这些实践,开发者能有效提升Java应用的安全防护水平。
6 1
|
2天前
|
Java 开发者
在Java编程中,if-else与switch作为核心的条件控制语句,各有千秋。if-else基于条件分支,适用于复杂逻辑;而switch则擅长处理枚举或固定选项列表,提供简洁高效的解决方案
在Java编程中,if-else与switch作为核心的条件控制语句,各有千秋。if-else基于条件分支,适用于复杂逻辑;而switch则擅长处理枚举或固定选项列表,提供简洁高效的解决方案。本文通过技术综述及示例代码,剖析两者在性能上的差异。if-else具有短路特性,但条件增多时JVM会优化提升性能;switch则利用跳转表机制,在处理大量固定选项时表现出色。通过实验对比可见,switch在重复case值处理上通常更快。尽管如此,选择时还需兼顾代码的可读性和维护性。理解这些细节有助于开发者编写出既高效又优雅的Java代码。
7 2
|
1天前
|
Java
java开启线程的四种方法
这篇文章介绍了Java中开启线程的四种方法,包括继承Thread类、实现Runnable接口、实现Callable接口和创建线程池,每种方法都提供了代码实现和测试结果。
java开启线程的四种方法
|
2天前
|
Java 开发者
在Java编程的广阔天地中,if-else与switch语句犹如两位老练的舵手,引领着代码的流向,决定着程序的走向。
在Java编程中,if-else与switch语句是条件判断的两大利器。本文通过丰富的示例,深入浅出地解析两者的特点与应用场景。if-else适用于逻辑复杂的判断,而switch则在处理固定选项或多分支选择时更为高效。从逻辑复杂度、可读性到性能考量,我们将帮助你掌握何时选用哪种语句,让你在编程时更加得心应手。无论面对何种挑战,都能找到最适合的解决方案。
6 1
|
2天前
|
搜索推荐 Java 程序员
在Java编程的旅程中,条件语句是每位开发者不可或缺的伙伴,它如同导航系统,引导着程序根据不同的情况做出响应。
在Java编程中,条件语句是引导程序根据不同情境作出响应的核心工具。本文通过四个案例深入浅出地介绍了如何巧妙运用if-else与switch语句。从基础的用户登录验证到利用switch处理枚举类型,再到条件语句的嵌套与组合,最后探讨了代码的优化与重构。每个案例都旨在帮助开发者提升编码效率与代码质量,无论是初学者还是资深程序员,都能从中获得灵感,让自己的Java代码更加优雅和专业。
5 1
|
2天前
|
Java
在Java编程的广阔天地中,条件语句是控制程序流程、实现逻辑判断的重要工具。
在Java编程中,if-else与switch作为核心条件语句,各具特色。if-else以其高度灵活性,适用于复杂逻辑判断,支持多种条件组合;而switch在多分支选择上表现优异,尤其适合处理枚举类型或固定选项集,通过内部跳转表提高执行效率。两者各有千秋:if-else擅长复杂逻辑,switch则在多分支选择中更胜一筹。理解它们的特点并在合适场景下使用,能够编写出更高效、易读的Java代码。
5 1
|
4天前
|
存储 缓存 安全
深度剖析Java HashMap:源码分析、线程安全与最佳实践
深度剖析Java HashMap:源码分析、线程安全与最佳实践
|
4天前
|
设计模式 算法 Java
Java编程中的设计模式:简化复杂性的艺术
在Java的世界中,设计模式如同一位智慧的导师,指引着开发者们在复杂的编码迷宫中找到出口。本文将深入浅出地探讨几种常见的设计模式,通过实例演示如何在Java项目实践中运用这些模式,从而提升代码的可维护性和扩展性。无论你是新手还是资深开发者,这篇文章都将为你打开一扇通往高效编码的大门。
12 1