专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 2022年Java并发-多线程的学习指南

2022年Java并发-多线程的学习指南

更新时间:2022-04-07 16:58:57 来源:赢咖4 浏览913次

Java并发(多线程)。本文介绍如何使用Java进行并发编程。它涵盖了并行编程、不变性、线程、执行器框架(线程池)、期货、可调用的CompletableFuture和fork-join框架的概念。

Java并发学习

1.什么是并发?

并发是并行运行多个程序或程序的几个部分的能力。如果一项耗时的任务可以异步或并行执行,这将提高程序的吞吐量和交互性。

现代计算机在一个CPU中具有多个CPU或多个内核。利用这些多核的能力可能是成功的大容量应用程序的关键。

2.进程与线程

一个进程独立运行并与其他进程隔离。它不能直接访问其他进程中的共享数据。进程的资源,例如内存和CPU时间,是通过操作系统分配给它的。

线程是所谓的轻量级进程。它有自己的调用栈,但可以访问同一进程中其他线程的共享数据。每个线程都有自己的内存缓存。如果一个线程读取共享数据,它会将这些数据存储在自己的内存缓存中。

线程可以重新读取共享数据。

默认情况下,Java应用程序在一个进程中运行。在Java应用程序中,您使用多个线程来实现并行处理或异步行为。

3.并发收益的限制

在Java应用程序中,您使用多个线程来实现并行处理或异步行为。并发承诺更快地执行某些任务,因为这些任务可以分为子任务,并且这些子任务可以并行执行。当然,运行时间受到可以并行执行的任务部分的限制。

理论上可能的性能增益可以通过以下称为阿姆达尔定律的规则来计算。

如果F是程序不能并行运行的百分比,N是进程数,则最大性能增益为1/(F+((1-F)/N))。

4.并发问题

线程有自己的调用栈,但也可以访问共享数据。因此,您有两个基本问题,可见性和访问问题。

如果线程A读取后来由线程B更改的共享数据并且线程A不知道此更改,则会出现可见性问题。

如果多个线程同时访问和更改相同的共享数据,则可能会出现访问问题。

可见性和访问问题可能导致:

活跃度失败:由于数据并发访问中的问题,例如死锁,程序不再反应。

安全故障:程序创建了不正确的数据。

5.进程和线程

Java程序在自己的进程中运行,默认情况下在一个线程中运行。Java通过代码支持线程作为Java语言的一部分Thread。Java应用程序可以通过此类创建新线程。

Java 1.5还为包的并发提供了改进的支持java.util.concurrent。

6.锁和线程同步

Java提供了锁来保护代码的某些部分,以便同时由多个线程执行。锁定某个方法或Java类的最简单方法是使用synchronized关键字定义方法或类。

Java中的synchronized关键字确保:

只有一个线程可以同时执行一段代码

进入同步代码块的每个线程都会看到由同一锁保护的所有先前修改的效果

对于线程块的互斥访问和线程之间的可靠通信,同步是必需的。

您可以使用synchronized关键字来定义方法。这将确保只有一个线程可以同时进入该方法。另一个调用这个方法的线程会一直等到第一个线程离开这个方法。

public synchronized void critial() {
    // some thread critical stuff
    // here
}

您还可以使用synchronized关键字来保护方法中的代码块。该块由一个键保护,该键可以是字符串或对象。这把钥匙叫做锁。

所有受同一个锁保护的代码只能由一个线程同时执行。

例如下面的数据结构将确保只有一个线程可以访问add()andnext()方法的内部块。

package de.vogella.pagerank.crawler;

import java.util.ArrayList;
import java.util.List;

/**
 * Data structure for a web crawler. Keeps track of the visited sites and keeps
 * a list of sites which needs still to be crawled.
 *
 * @author Lars Vogel
 *
 */
public class CrawledSites {
    private List<String> crawledSites = new ArrayList<String>();
    private List<String> linkedSites = new ArrayList<String>();

    public void add(String site) {
        synchronized (this) {
            if (!crawledSites.contains(site)) {
                linkedSites.add(site);
            }
        }
    }

    /**
     * Get next site to crawl. Can return null (if nothing to crawl)
     */
    public String next() {
        if (linkedSites.size() == 0) {
            return null;
        }
        synchronized (this) {
            // Need to check again if size has changed
            if (linkedSites.size() > 0) {
                String s = linkedSites.get(0);
                linkedSites.remove(0);
                crawledSites.add(s);
                return s;
            }
            return null;
        }
    }

}

以上就是赢咖4小编介绍的"2022年Java并发-多线程的学习指南",希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为您服务。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>