Java多线程详细教程

一、线程的概念

1、进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础,是一个程序的一次执行过程;一个进程包括由操作系统分配的内存空间,包含了一个或多个线程。

2、线程

线程(Thread)是操作系统能够进行运算调度的最小单位,又称为是轻量级的进程。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程。一个线程不能独立的存在,它是进程的一部分,必须依赖进程而存在。多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。

3、一个线程的生命周期

线程的生命周期是一个动态执行的一个过程,他也有一个从产生到结束的过程,这个过程就是线程的生命周期,我们把线程的生命周期描述为五种状态:创建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead)。下面是一个简单的线程生命周期介绍。

在这里插入图片描述

(1)创建

当创建Thread类的一个线程对象后,该线程对象就处于新建状态,它将保持这个状态直到程序 start() 这个线程。

(2)就绪

当线程Thread对象调用了start()方法之后,该线程就进入就绪状态,此时该线程等待获取CPU的资源,抢到CPU资源之后就到了运行状态。

(3)运行

当就绪的线程获取到CPU资源之后就进入了运行状态,这时会执行run()方法里面的内容。

(4)阻塞

如果一个线程因为某些异常原因执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态,可以重新进入到就绪状态。

(5)死亡

一个运行状态的线程完成任务或者其他终止条件发生时,那么线程就要被销毁,释放资源,意味着一个线程的终结。

二、线程的创建方式

Java中线程的基本创建方式有三种:

1、通过实现 Runnable 接口
2、通过继承 Thread 类
3、通过 Callable 和 Future 创建有返回值的线程。

三、线程控制的基本方法

线程的启动

线程的启动需要调用Thread的start方法,不能直接调用run方法,如果直接调用run方法相当于方法调用。

线程的终止

当run方法返回,线程终止,一旦线程终止后不能再次启动;线程的终止可以调用线程的interrupt方法。

Thread相关方法

public void start()
使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

public void run()
如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

public final void setName(String name)
修改线程名字。

public final void setPriority(int priority)
更改线程的优先级。

public final void setDaemon(boolean on)
修改线程为守护线程或用户线程。

public final void join()
插入线程/插队线程

public void interrupt()
中断线程

public final boolean isAlive()
检查线程是否还在活动

上述方法是被 Thread 对象调用的,下面介绍Thread的静态方法

public static void yield()
暂停当前正在执行的线程对象,并执行其他线程。

public static void sleep(long millisec)
让当前线程休眠指定时间,单位毫秒

public static boolean holdsLock(Object x)
当且仅当当前线程在指定的对象上保持监视器锁时,才返回 truepublic static Thread currentThread()
返回对当前正在执行的线程对象的引用。

public static void dumpStack()
将当前线程的堆栈跟踪打印至标准错误流。

四、线程创建详细描述

线程的创建方式共有三种,其中常用的Runnable 接口和Thread 类是没有返回值的,而通过 Callable 和 Future 创建线程的方式适用于需要有返回值的线程;下面将做详细说明。

1、通过实现 Runnable 接口来创建线程

下面是一个简单的通过实现 Runnable 接口来创建线程的示例:

/**
 * 实现Runnable接口并重写run()方法
 */
public class RunnableDemo implements Runnable{
   
   
    @Override
    public void run() {
   
   
        for (int i = 0; i < 10; i++) {
   
   
            //获取当前线程对象
            Thread t = Thread.currentThread();
            System.out.println("我是线程"+t.getName());
        }

    }
    public static void main(String[] args) {
   
   
        //创建demo对象
        RunnableDemo demo1 = new RunnableDemo();
        RunnableDemo demo2 = new RunnableDemo();
        Thread thread1= new Thread(demo1,"1");
        Thread thread2 = new Thread(demo2);
        //设置线程名称
        thread2.setName("2");
        //启动线程
        thread1.start();
        thread2.start();
    }
}

运行以上代码之后得到下面的结果,可以看到两个线程是交替执行:

我是线程1
我是线程2
我是线程2
我是线程2
我是线程1
我是线程2
我是线程2
我是线程1
我是线程1
我是线程2
我是线程2
我是线程2
我是线程2
我是线程2
我是线程1
我是线程1
我是线程1
我是线程1
我是线程1
我是线程1

Process finished with exit code 0

2、通过继承Thread来创建线程

下面是一个简单的通过继承Thread来创建线程的示例:


public class MyThread extends Thread{
   
   
    @Override
    public void run() {
   
   
        for (int i = 0; i < 10; i++) {
   
   
            System.out.
### 关于Java多线程详细教程 对于希望深入学习Java多线程技术的学习者来说,《Java多线程并行编程》PDF版本是一个非常有价值的参考资料[^3]。该文档不仅提供了理论知识,还包含了实际应用中的案例分析以及代码实现细节。 #### Java多线程的核心概念 在Java中,多线程是一种允许程序并发执行多个任务的能力。通过创建`Thread`对象或者实现`Runnable`接口的方式可以启动一个新的线程。此外,还可以利用更高级别的抽象工具如`ExecutorService`来管理线程池,从而提高性能和可维护性[^4]。 以下是几个重要的主题: 1. **线程的基础操作** - 创建线程的方法:继承`Thread`类或实现`Runnable`接口。 - 启动线程:调用`start()`方法而非直接调用`run()`方法。 2. **同步控制** 使用`synchronized`关键字确保共享资源的安全访问,防止数据竞争条件的发生[^3]。 3. **锁机制** - ReentrantLock 提供了比 synchronized 更灵活的功能,比如支持公平锁、尝试获取锁等特性。 - ReadWriteLock 可以区分读写权限,提升吞吐量。 4. **线程间通信** 利用等待/通知模式(wait() 和 notify()/notifyAll() 方法),使不同线程能够相互协作完成复杂业务逻辑。 5. **线程池的应用** 线程池的主要目的是减少每次新建销毁线程所带来的开销,同时限制系统中活动线程的数量以防耗尽内存资源。常见的几种预定义线程池包括FixedThreadPool, CachedThreadPool, SingleThreadExecutor等等。 ```java // 示例代码展示如何使用Executors框架构建固定大小的线程池 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(10); Runnable task = () -> System.out.println("Executing Task"); for(int i=0;i<10;i++) { executor.submit(task); } executor.shutdown(); } } ``` 6. **异常处理与调试技巧** 当某个子线程抛出了未被捕获的Exception时,默认情况下它只会打印堆栈跟踪然后终止自己而不影响主线程或其他兄弟姐妹们继续运行下去;但如果想要捕获这些错误以便采取适当措施,则可以通过设置UncaughtExceptionHandler来达成目标[^3]。 7. **高级话题** 探讨CompletableFuture API 的异步编程模型,它可以链式组合多个阶段的操作,并且自动处理回调地狱问题。另外还有ForkJoinPool专门针对分治算法优化设计而成的新一代轻量级工作窃取型线程池结构。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值