Java 进阶多线程(一)

简介: Java 进阶多线程

一、多线程

1、继承Thread类(方式一)

1)实现多线程

继承Thread类

重写run()方法

创建线程对象

调用start()方法启动

调用run方法会当成普通方法执行,只有调用start方法才是启动一个新的线程执行

2)优缺点

优点

编码简单

缺点

是单继承,线程类继承Thread后,不能继承其他类,不便于扩展

2、实现Runnable接口(方式二)

1)实现多线程

定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法

创建MyRunnable对象

把MyRunnable任务对象交给Thread线程对象处理

调用线程对象的start()方法启动线程

2)实现多线程(匿名内部类方式)

创建Runnable的匿名内部类对象

交给Thread处理

调用线程对象的start()启动线程

3)优缺点

优点

实现了Runnale接口,可以继续继承和实现

缺点

线程有执行结果是不能直接返回

3、实现Callable、FutureTask接口(方式三)

1)实现多线程

创建Callable接口实现类,重写call()方法,封装

用FutureTask把Callable对象封装成线程任务对象

线程任务对象交给Thread处理,调用start()方法启动线程,执行任务

执行完毕后,通过FutureTask的get方法去获取任务执行的结果

2)优缺点

优点

线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。

可以在线程执行完毕后去获取线程执行的结果。

缺点

编码复杂

方法名 解释

public FutureTask<>(Callable call) 把Callable对象封装成FutureTask对象

public V get() throws Exception 获取线程执行call方法返回的结果

4、Thread线程

1)Thread的构造器

构造器 解释

public Thread(String name) 为当前线程指定名称

public Thread(Runnable target) 封装Runnable对象成为线程对象

public Thread(Runnable target ,String name ) 封装Runnable对象成为线程对象,并指定线程名称

e609cccd993399f78bd2b5ba8e22a1d.png

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Runnable "+Thread.currentThread().getName()+" ===>> "+i);
        }
    }
}
public class ClassStructure {
    public static void main(String[] args){
        MyRunnable myRunnable = new MyRunnable();
        //分配一个带有指定目标新的线程对象
        Thread thread = new Thread(myRunnable);
        //获取当前线程名称
        String name = thread.getName();
        System.out.println("当前名称-1:"+name);
        //设置新的名称
        thread.setName("Thread-1-新");
        String newName = thread.getName();
        System.out.println("当前名称-1:"+ newName);
        //启动多线程
        thread.start();
        MyRunnable mr = new MyRunnable();
        //分配一个带有指定目标新的线程对象并指定名称
        Thread td = new Thread(mr,"指定名称:");
        String strName = td.getName();
        System.out.println("当前名称-2:"+ strName);
        td.start();
    }
}

5、Thread的方法

1)Thread获取和设置线程名称

方法名 解释

String getName() 获取当前线程的名称,默认线程名称是Thread-索引

void setName(String name) 将此线程的名称更改为指定的名称,通过构造器也可以设置线程名称

0d013aeec7c62cd3ca576069644cda8.png

public class ClassStructure {
    public static void main(String[] args){
        Thread thread = new Thread();
        String name = thread.getName();
        System.out.println(name);
        thread.setName("线程1");
        String nameNew = thread.getName();
        System.out.println(nameNew);
    }
}

2)Thread类获得当前线程的对象

方法名 解释

public static Thread currentThread() 返回对当前正在执行的线程对象的引用

注意:

1、此方法是Thread类的静态方法,可以直接使用Thread类调用。

2、这个方法是在哪个线程执行中调用的,就会得到哪个线程对象。

public class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }
    @Override
    public void run() {
        super.run();
        for (int i = 0; i < 10; i++) {
            //获得当前正在执行的线程对象
            Thread td = Thread.currentThread();
            //获取当前线程名称
            System.out.println(td.getName() + i);
        }
    }
}

3)Thread类的线程休眠方法:

方法名 解释

public static void sleep(long time) 让当前线程休眠指定的时间后再继续执行,单位为毫秒

8d4f641e40c44488e797471899e8f1d.png

public class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }
    @Override
    public void run() {
        super.run();
        for (int i = 0; i < 10; i++) {
            //获得当前正在执行的线程对象
            Thread td = Thread.currentThread();
            //获取当前线程名称
            System.out.println(td.getName() + i);
        }
    }
}
public class ClassStructure {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable mr = new MyRunnable();
        //分配一个带有指定目标新的线程对象并指定名称
        Thread td = new Thread(mr,"指定名称:");
        String strName = td.getName();
        System.out.println("当前名称-2:"+ strName);
        System.out.println(System.currentTimeMillis());
        //暂停3秒
        Thread.sleep(3000);
        System.out.println(System.currentTimeMillis());
        td.start();
    }
}

二、线程安全

多个线程同时访问同一个共享资源且存在修改该资源

三、线程同步

概念

解决线程安全问题

保证线程安全

多个线程实现先后依次访问共享资源,可以解决安全问题

思想

加锁:让多个线程实现先后依次访问共享资源,可以解决安全问题

1、同步代码块

原理

每次只能一个线程进入,执行完毕后自动解锁,其它线程才可以进来执行

作用

线程安全问题的核心代码给上锁

实现线程安全

对出现问题的核心代码是使用synchronized进行加锁

每次只能一个线程占锁进入执行

格式

synchronized(同步锁对象) {
  操作共享资源的代码(核心代码)
}

同步锁对象要求

对于实例方法建议使用this作为锁对象

对于静态方法建议使用字节码(类名.class)对象作为锁对象

2、同步方法

原理

每次只能一个线程进入,执行完毕后自动解锁,其它线程才可以进来执行

作用

线程安全问题的核心代码给上锁

格式

实现线程安全

对出现问题的核心代码是使用synchronized进行加锁

每次只能一个线程占锁进入执行

修饰符 synchronized 返回值类型 方法名称(形参列表) {
  操作共享资源的代码
}

同步锁对象要求

对于实例方法建议使用this作为锁对象

对于静态方法建议使用字节码(类名.class)对象作为锁对象

底层原理

如果方法是实例方法:同步方法默认用this作为的锁对象。但是代码要高度面向对象

如果方法是静态方法:同步方法默认用类名.class作为的锁对象

3、Lock锁

原理

锁对象Lock,使用更加灵活、方便

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作

Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来构建Lock锁对象

方法名 解释

public ReentrantLock() 获得Lock锁的实现类对象

void lock() 加锁

void unlock() 解锁


相关文章
|
6天前
|
安全 Java 调度
Java编程时多线程操作单核服务器可以不加锁吗?
Java编程时多线程操作单核服务器可以不加锁吗?
21 2
|
10天前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
12天前
|
Java 开发者
Java中的多线程基础与应用
【9月更文挑战第22天】在Java的世界中,多线程是一块基石,它支撑着现代并发编程的大厦。本文将深入浅出地介绍Java中多线程的基本概念、创建方法以及常见的应用场景,帮助读者理解并掌握这一核心技术。
|
8天前
|
Java 调度
Java-Thread多线程的使用
这篇文章介绍了Java中Thread类多线程的创建、使用、生命周期、状态以及线程同步和死锁的概念和处理方法。
Java-Thread多线程的使用
|
14天前
|
Java
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
22 7
|
13天前
|
Java 程序员
Java中的多线程基础与实践
【9月更文挑战第21天】本文旨在引导读者深入理解Java多线程的核心概念,通过生动的比喻和实例,揭示线程创建、同步机制以及常见并发工具类的使用。文章将带领读者从理论到实践,逐步掌握如何在Java中高效地运用多线程技术。
|
11天前
|
Java 调度 开发者
Java中的多线程编程:从基础到实践
本文旨在深入探讨Java多线程编程的核心概念和实际应用,通过浅显易懂的语言解释多线程的基本原理,并结合实例展示如何在Java中创建、控制和管理线程。我们将从简单的线程创建开始,逐步深入到线程同步、通信以及死锁问题的解决方案,最终通过具体的代码示例来加深理解。无论您是Java初学者还是希望提升多线程编程技能的开发者,本文都将为您提供有价值的见解和实用的技巧。
15 2
|
13天前
|
Java 数据处理
Java中的多线程编程:从基础到实践
本文旨在深入探讨Java中的多线程编程,涵盖其基本概念、创建方法、同步机制及实际应用。通过对多线程基础知识的介绍和具体示例的演示,希望帮助读者更好地理解和应用Java多线程编程,提高程序的效率和性能。
19 1
|
6天前
|
Java 数据中心 微服务
Java高级知识:线程池隔离与信号量隔离的实战应用
在Java并发编程中,线程池隔离与信号量隔离是两种常用的资源隔离技术,它们在提高系统稳定性、防止系统过载方面发挥着重要作用。
6 0
|
8天前
|
Java 数据处理 调度
Java中的多线程编程:从基础到实践
本文深入探讨了Java中多线程编程的基本概念、实现方式及其在实际项目中的应用。首先,我们将了解什么是线程以及为何需要多线程编程。接着,文章将详细介绍如何在Java中创建和管理线程,包括继承Thread类、实现Runnable接口以及使用Executor框架等方法。此外,我们还将讨论线程同步和通信的问题,如互斥锁、信号量、条件变量等。最后,通过具体的示例展示了如何在实际项目中有效地利用多线程提高程序的性能和响应能力。
下一篇
无影云桌面