Java线程

一 程序、进程、线程

程序:

        为完成某种特定功能,使用计算机语言编写一系列指令的集合,即静态代码。

进程:

        正在执行的程序,是操作系统分配资源的最小单位。

线程:

        进程内部的最小执行单元,是操作系统进行任务调度的最小单元

备注:

        早期cpu执行是以进程为单位,后来cpu执行改为更小的线程为单位,一个程序内有多个线程,只需切换线程即可。

二 进程和线程的关系

1.一个进程中可以包含多个线程,线程必须属于某一个线程,不能独立存在。

2.一个进程中必须有一个主线程,但在主线程中可以创建其他子线程。

3.一个进程的所有线程可以共享该进程的所有资源。

三 Java如何创建线程

继承Thread类的方式:

        1.在Java中要实现线程,最简单的方式就是扩展Thread类,重写其中的run方法。

        2.Thread类中的run方法本身并不执行任何操作,如果我们重写了run方法,当线程启动时,它将执行 run方法。

定义:

public class c extends Thread{
    @Override
    public void run() {

    }
}

调用:

public class c {
    public static void main(String[] args) {
        Thread thread = new Thread();
        thread.start();
    }
}

实现Runnable接口的方式:

        1. java.lang.Runnable接口中仅仅只有一个抽象方法,

@Override
    public void run() {
        
    }

        2.也可以通过实现Runnable接口的方式来实现线程,只需要实现其中的run方法即可。

        3. Runnable接口的存在主要是为了解决Java中不允许多继承的问题。

区别:

        继承Thread,由于Java是单继承的,所以就不能继承其他类了,实现Runnable接口的方式,可以继承其它类

四 Thread类中的方法

方法原型

说明

void start()

启动线程

final String getName()

返回线程的名称

final void setPriority(int newPriority)

设置线程的优先级

final int getPriority()

返回线程的优先级

final void join

等待线程终止

static Thread currentThread()

返回对当前正在执行的线程对象的引用

static void sleep(long millis)

让当前正在执行的线程休眠(暂停执行), 休眠时间由milli s(毫秒)指定

yield()

线程让步

五 线程状态

新建:

        当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。

new Thread()/new Thread的子类

就绪:

        处于新建状态的线程被start()后,将进入线程队列等待CPU时 间片,此时它已具备了运行的条件,只是没分配到CPU资源。

Thread.start();

运行:

        当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能。

@Override
    public void run() {

    }

阻塞:

        在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU并临时中止自己的执行,进入阻塞状态。

Thread.sleep();

死亡:

        线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束。

六 守护线程

        Java中的线程分为两类:用户线程和守护线程

public class DaemonThread  extends Thread{

    @Override
    public void run() {
        int i = 0;
        while (true){
            System.out.println("DaemonThread:"+i++);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        DaemonThread daemonThread = new DaemonThread();
        daemonThread.setDaemon(true);
        daemonThread.start();
        for (int i = 0; i <1000 ; i++) {
            System.out.println("main:"+i);
        }
    }
}

七 多线程

定义:

        只一个程序内部,可以创建多个线程执行不同的任务。

何时需要线程?

        1.需执行多个功能时,例如:杀毒软件,QQ等。

        2.程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、 网络操作、搜索等。

多线程的优点:

        1.提高程序的响应。

        2.提高cpu的利用率。

        3.改善程序结构。

多线程的缺点:

        1.占用内存。

        2.占用cpu资源,需要对多线程进行管理。

        3.多线程同时对共享资源进行访问,如果不加以控制就会产生安全问题。

多线程安全问题:

      通过sycnhronized和lock把同代码块锁住防止多个线程同时访问同一个对象。  

八 线程同步

并发:

        在一个时间段内,多个任务依次执行。

并行:

        真正意义上的同时执行,一个时间节点上有多个任务同时执行。

同步锁:

        同步锁可以是任何对象,必须唯一,保证多个线程获得是同一个对象(用 来充当锁标记)。

同步执行过程:

        1.第一个线程访问,锁定同步对象,执行其中代码。

        2.第二个线程访问,发现同步对象被锁定,无法访问。

        3.第一个线程访问完毕,解锁同步对象。

        4.第二个线程访问,发现同步对象没有锁,然后锁定并访问。

synchronized关键字:

synchronized (同步锁){
// 需要被同步的代码;
}
public synchronized void show (String name){
// 需要被同步的代码;
}

九 LOCK

lock:

         1.从JDK 5.0开始,Java提供了更强大的线程同步机制-通过显式定义同步锁对象来实现同步。同步锁使用Lock对象充当。

        2.java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。

        3.ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显式加锁、释放锁。

lock和synchronized的区别:

        1.实现原理不同:ReentranrLock是一种java代码层面的控制实现,而synchronized是关键字,依靠的底层编译后的指令实现。

        2.加锁范围不同:ReentrantLock只能对一段代码块加锁,而synchronized可以对代码块和方法加锁。

        3.加锁方式不同:ReentrantLock是手动加锁释放锁,而synchronized是隐式的自动加锁,自动释放锁。

十 线程通信

定义:

        线程通讯指的是多个线程通过相互牵制,相互调度,即线程间的相互作用。

方法:

        wait一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。

        notify一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。

        notifyAll一旦执行此方法,就会唤醒所有被wait的线程。

sleep和wait的区别:

        sleep()让线程阻塞指定时间,时间到后,自己唤醒进入到就绪状态,不会释放同步锁,是Thread中的方法。

        wait()让线程进入等待(阻塞),不会自己唤醒,必须通过notify(),notifyAll()唤醒,

等待时会释放同步锁,是Object类中的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中,线程是程序执行的基本单元,用于并发执行任务。每个线程都有自己的生命周期,包括创建、运行、阻塞和终止。线程的创建可以通过继承Thread类或实现Runnable接口来实现。 线程池则是Java中一种高效的线程管理机制,它预先创建一定数量的工作线程,并在需要执行任务时从线程池中获取线程进行处理,当任务完成后,线程会返回到线程池等待下一次调度,而不是立即结束。这样可以避免频繁地创建和销毁线程带来的开销,提高系统的性能和资源利用率。 以下是Java线程和线程池的一些关键点: 1. **线程创建**: - **继承Thread类**:创建自定义线程类并重写run()方法。 - **实现Runnable接口**:创建Runnable接口的实现类,提供run()方法,然后用Thread构造函数创建Thread实例。 2. **线程状态**: - 新建(New):线程对象被创建但还未启动。 - 运行(Runnable):线程正在执行run()方法。 - 阻塞(Blocked):线程因某个条件而暂停,如I/O操作等待数据。 - 等待(Waiting):线程在调用wait()方法后,进入等待状态,直到被其他线程唤醒。 - 守护(Terminated):非守护线程完成或主线程结束,守护线程自动退出。 3. **线程池组件**: - ExecutorService:线程池的核心接口,提供了提交任务和控制线程的方法。 - ThreadPoolExecutor:实现了ExecutorService,包含核心线程数、最大线程数、任务队列等配置。 - ScheduledThreadPoolExecutor:支持定时和周期性任务。 4. **线程池的优势**: - **资源复用**:减少线程创建和销毁的开销。 - **线程管理和调度**:灵活设置线程数量、线程优先级和任务执行策略。 - **避免死锁**:由于任务有顺序地等待特定资源,减少了死锁的可能性。 - **可扩展性**:随着任务增加,线程池可以根据需要动态调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值