16.Java基础&线程

        大家好,欢迎来到 Java 小助手的线程教学课程!今天,我们将深入探讨 Java 中线程的方方面面,从基础的线程介绍到高阶技术的线程同步和状态,让你真正掌握多线程编程的精髓。准备好迎接线程世界的挑战了吗?让我们开始吧!🧵🔄

1. 线程介绍

        首先,让我们从线程的基础入手。了解如何创建线程、线程的生命周期以及如何合理运用多线程提升程序性能。通过本节,你将能够轻松驾驭 Java 多线程编程。

创建线程的两种方式:
(1)继承 Thread 类

通过继承 Thread 类,我们可以创建一个新的线程。需要重写 run 方法,该方法中包含了线程的执行逻辑。

class MyThread extends Thread {
    public void run() {
        // 线程执行的代码
    }
}


// 创建并启动线程
MyThread myThread = new MyThread();
myThread.start();
myThread.start();
(2)实现 Runnable 接口

另一种创建线程的方式是实现 Runnable 接口。这样可以更好地避免 Java 单继承的限制,同时提高代码的可维护性。

class MyRunnable implements Runnable {
    public void run() {
        // 线程执行的代码
    }
}


// 创建线程并传入实现了 Runnable 接口的对象
Thread thread = new Thread(new MyRunnable());
thread.start();

    通过实现Runnable接口,使得该类有了多线程类的特征。run()方法是多线程程序的一个执行目标。所有的多线程代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类。

    在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。

    实际上所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是继承Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程编程的基础。

tips:Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。

学习目标: 理解线程的基本概念,掌握线程的创建和启动方法。

Thread和Runnable的区别:

    如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

总结:

实现Runnable接口比继承Thread类所具有的优势:

1. 适合多个相同的程序代码的线程去共享同一个资源。

2. 可以避免java中的单继承的局限性。

3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。

4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

扩充:在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进程。

2. 线程同步

学习线程同步的原因:

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

在多线程环境下,线程同步是一个必须要解决的问题。学习关键字 synchronized 和 Lock 接口的使用,掌握如何避免数据竞争和保持数据一致性。

  当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题。要解决多线程并发访问一个资源的安全性问题,Java中提供了同步机制(synchronized)来解决。

// 使用 synchronized 实现同步方法
public synchronized void synchronizedMethod() {
    // 同步代码块
}


// 使用 Lock 接口实现同步
Lock lock = new ReentrantLock();
public void lockExample() {
    lock.lock();
    try {
        // 同步代码块
    } finally {
        lock.unlock();
    }
}

​​​

同步锁:

对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁.

1. 锁对象 可以是任意类型。

2. 多个线程对象 要使用同一把锁。

注意:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着(BLOCKED)。

同步方法:

    使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。

Lock锁

        java.util.concurrent.locks.Lock 机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作,同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。

Lock锁也称同步锁,加锁与释放锁方法化了,如下:

public void lock() :加同步锁。

public void unlock() :释放同步锁。

示例代码:

public class Ticket implements Runnable{
private int ticket = 100;
Lock lock = new ReentrantLock();
/*
* 执行卖票操作
*/
@Override
public void run() {
//每个窗口卖票的操作
//窗口 永远开启
while(true){
lock.lock();
if(ticket>0){//有票 可以卖
//出票操作
//使用sleep模拟一下出票时间
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto‐generated catch block
e.printStackTrace();
}
//获取当前线程对象的名字
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖:"+ticket‐‐);
}
lock.unlock();
}
}
}

学习目标: 掌握线程同步的基本原理和常用方法,避免多线程环境下的数据安全问题。

3. 线程状态

了解线程在运行过程中的状态对于调试和优化程序非常重要。学习不同线程状态的转换以及如何获取线程的状态信息。

当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,有几种状态呢?在API中 java.lang.Thread.State 这个枚举中给出了六种线程状态:

这里先列出各个线程状态发生的条件

线程状态一览:
  • 新建(New): 线程被创建但还未启动。

  • 就绪(Runnable): 线程已经被创建且可以运行,等待获取 CPU 时间片。

  • 运行(Running): 线程正在执行。

  • 阻塞(Blocked): 线程被阻塞,等待获取一个排它锁。

    图片

  • 等待(Waiting): 线程进入等待状态,等待其他线程通知唤醒。

    图片

  • 超时等待(Timed Waiting): 在等待状态的基础上设置了超时时间。

    图片

  • 终止(Terminated): 线程执行完毕或者因异常退出,进入终止状态。

// 获取线程状态
Thread.State state = thread.getState();
System.out.println("线程状态:" + state);

一条有意思的tips:

我们在翻阅API的时候会发现Timed Waiting(计时等待) 与 Waiting(无限等待) 状态联系还是很紧密的,比如Waiting(无限等待) 状态中wait方法是空参的,而timed waiting(计时等待) 中wait方法是带参的。这种带参的方法,其实是一种倒计时操作,相当于我们生活中的小闹钟,我们设定好时间,到时通知,可是如果提前得到(唤醒)通知,那么设定好时间在通知也就显得多此一举了,那么这种设计方案其实是一举两得。如果没有得到(唤醒)通知,那么线程就处于Timed Waiting状态,直到倒计时完毕自动醒来;如果在倒计时期间得到(唤醒)通知,那么线程从Timed Waiting状态立刻唤醒。

学习目标: 能够通过获取线程状态更好地理解和调试多线程程序。

4. 互动结语

在这个丰富的线程知识之旅中,你掌握了哪些有趣的技能?有没有遇到令人挑战的问题?留言告诉我吧!在这个互动环节,我们将一同分享经验,共同进步!💬✨

📘 更多学习资源

想要更深入地学习线程的高级技术?推荐(微信搜索:gh_3aeecc6ab938(公众号)获取相关课程资源。

🔗 深度学习

欢迎查阅 Java 官方文档以及参与线程相关的技术社区,与其他开发者分享经验,解决问题。在这个广阔而有趣的线程世界,让我们一同深度学习!欢迎讨论分享。

学习目标: 激发学习兴趣,深入学习线程的更多高级应用和技术。

#Java编程 #多线程 #线程同步 #线程状态 #程序性能 #技术分享 #编程深度解析

J2EE7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值