精华内容
下载资源
问答
  • 通过HttpURLConnection连接网络通过RandomAccessFile建立随机访问文件,确定大小的空白文件并且可以指定读取和存储的位置通过消息头Range设置断点下载import java.io.BufferedReader;import java.io.File;import ...

    2d30d063d1acd4871ad266828fa9d755.png

    通过HttpURLConnection连接网络

    通过RandomAccessFile建立随机访问文件,确定大小的空白文件并且可以指定读取和存储的位置

    通过消息头Range设置断点下载

    import java.io.BufferedReader;

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.InputStream;

    import java.io.InputStreamReader;

    import java.io.RandomAccessFile;

    import java.net.HttpURLConnection;

    import java.net.URL;

    public class MutileThreadDownload {

    /**

    * 线程的数量

    */

    private static int threadCount = 3;

    /**

    * 每个下载区块的大小

    */

    private static long blocksize;

    /**

    * 正在运行的线程的数量

    */

    private static int runningThreadCount;

    /**

    * @param args

    * @throws Exception

    */

    public static void main(String[] args) throws Exception {

    // 服务器文件的路径

    String path = "http://192.168.1.100:8080/ff.exe";

    URL url = new URL(path);

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setRequestMethod("GET");

    conn.setConnectTimeout(5000);

    int code = conn.getResponseCode();

    if (code == 200) {

    long size = conn.getContentLength();// 得到服务端返回的文件的大小

    System.out.println("服务器文件的大小:" + size);

    blocksize = size / threadCount;

    // 1.首先在本地创建一个大小跟服务器一模一样的空白文件。

    File file = new File("temp.exe");

    RandomAccessFile raf = new RandomAccessFile(file, "rw"); //随机访问的文件,可以创建一个确定大小的空白文件并且可以指定读取和存储的位置

    raf.setLength(size);

    // 2.开启若干个子线程分别去下载对应的资源。

    runningThreadCount = threadCount;

    for (int i = 1; i <= threadCount; i++) {

    //http协议和java一样 也是从0开始,而且也是begin有效而end无效

    long startIndex = (i - 1) * blocksize;

    long endIndex = i * blocksize - 1;

    if (i == threadCount) {

    // 最后一个线程

    endIndex = size - 1;

    }

    System.out.println("开启线程:" + i + "下载的位置:" + startIndex + "~"

    + endIndex);

    new DownloadThread(path, i, startIndex, endIndex).start();

    }

    }

    conn.disconnect();

    }

    private static class DownloadThread extends Thread {

    private int threadId;

    private long startIndex;

    private long endIndex;

    private String path;

    public DownloadThread(String path, int threadId, long startIndex,

    long endIndex) {

    this.path = path;

    this.threadId = threadId;

    this.startIndex = startIndex;

    this.endIndex = endIndex;

    }

    @Override

    public void run() {

    try {

    // 当前线程下载的总大小

    int total = 0;

    File positionFile = new File(threadId + ".txt");

    URL url = new URL(path);

    HttpURLConnection conn = (HttpURLConnection) url

    .openConnection();

    conn.setRequestMethod("GET");

    // 接着从上一次的位置继续下载数据

    if (positionFile.exists() && positionFile.length() > 0) {// 判断是否有记录

    FileInputStream fis = new FileInputStream(positionFile);

    BufferedReader br = new BufferedReader(

    new InputStreamReader(fis));

    // 获取当前线程上次下载的总大小是多少

    String lasttotalstr = br.readLine();

    int lastTotal = Integer.valueOf(lasttotalstr);

    System.out.println("上次线程" + threadId + "下载的总大小:"

    + lastTotal);

    startIndex += lastTotal;

    total += lastTotal;// 加上上次下载的总大小。

    fis.close();

    }

    //设置消息头

    conn.setRequestProperty("Range", "bytes=" + startIndex + "-"

    + endIndex);

    conn.setConnectTimeout(5000);

    int code = conn.getResponseCode();

    System.out.println("code=" + code); //这里的code不是200 是206

    InputStream is = conn.getInputStream();

    File file = new File("temp.exe");

    RandomAccessFile raf = new RandomAccessFile(file, "rw");

    // 指定文件开始写的位置。

    raf.seek(startIndex);

    System.out.println("第" + threadId + "个线程:写文件的开始位置:"

    + String.valueOf(startIndex));

    int len = 0;

    byte[] buffer = new byte[512];

    while ((len = is.read(buffer)) != -1) {

    //之所以使用这个而不适用FileOutputStream是因为FileOutputStream有可能出现上传下载断掉之后数据还在硬盘缓冲区,没有真正输入到硬盘中,造成数据丢失。。

    //RandomAccessFile不仅可读可写,并且对数据都会立马更新。。 第二参数需要是rwd

    RandomAccessFile rf = new RandomAccessFile(positionFile,

    "rwd");

    raf.write(buffer, 0, len);

    //当前已下载的数据量

    total += len;

    rf.write(String.valueOf(total).getBytes());

    rf.close();

    }

    is.close();

    raf.close();

    } catch (Exception e) {

    e.printStackTrace();

    } finally {

    // 只有所有的线程都下载完毕后 才可以删除记录文件。

    synchronized (MutileThreadDownload.class) {

    System.out.println("线程" + threadId + "下载完毕了");

    runningThreadCount--;

    if (runningThreadCount < 1) {

    System.out.println("所有的线程都工作完毕了。删除临时记录的文件");

    for (int i = 1; i <= threadCount; i++) {

    File f = new File(i + ".txt");

    System.out.println(f.delete());

    }

    }

    }

    }

    }

    }

    }

    展开全文
  • 本文实例讲述了Python多线程下载文件的方法。分享给大家供大家参考。具体实现方法如下:import httplibimport urllib2import timefrom threading import Threadfrom Queue import Queuefrom time import sleepproxy ...

    本文实例讲述了Python多线程下载文件的方法。分享给大家供大家参考。具体实现方法如下:

    import httplib

    import urllib2

    import time

    from threading import Thread

    from Queue import Queue

    from time import sleep

    proxy = 'your proxy';

    opener = urllib2.build_opener( urllib2.ProxyHandler({'http':proxy}) )

    urllib2.install_opener( opener )

    ids = {};

    for i in range(1,110):

    try:

    listUrl = "http://www.someweb.net/sort/list_8_%d.shtml" % (i);

    print listUrl;

    page = urllib2.urlopen(listUrl).read();

    speUrl = "http://www.someweb.net/soft/";

    speUrlLen = len(speUrl);

    idx = page.find(speUrl,0);

    while idx!=-1:

    dotIdx = page.find(".",idx + speUrlLen);

    if dotIdx != -1:

    id = page[idx + speUrlLen:dotIdx];

    ids[id] = 1;

    idx = page.find("http://www.someweb.net/soft/",idx + speUrlLen);

    except:

    pass;

    q = Queue()

    NUM = 5

    failedId = [];

    def do_somthing_using(id):

    try:

    url = "http://www.someweb.net/download.php?softid=%s&type=dx" % (id);

    h2 = httplib.HTTPConnection("your proxy", "you port");

    h2.request("HEAD", url);

    resp = h2.getresponse();

    header = resp.getheaders();

    location = header[3][1];

    sContent = urllib2.urlopen(location).read();

    savePath = "C:\\someweb\\%s.rar" % (id);

    file=open(savePath,'wb');

    file.write(sContent);

    file.close();

    print savePath + " saved";

    except:

    pass;

    def working():

    while True:

    arguments = q.get()

    do_somthing_using(arguments)

    sleep(1)

    q.task_done()

    for i in range(NUM):

    t = Thread(target=working)

    t.setDaemon(True)

    t.start()

    for id in ids:

    q.put(id)

    q.join()

    希望本文所述对大家的Python程序设计有所帮助。

    本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

    本文系统来源:php中文网

    展开全文
  • 第1章Java多线程技能作为本书的第1章,重点是让读者快速进入Java多线程的学习,所以本章主要介绍Thread类的核心方法。Thread类的核心方法较多,读者应该着重掌握如下技术点:线程的启动;如何使线程暂停;如何使线程...

    第1章

    Java多线程技能

    作为本书的第1章,重点是让读者快速进入Java多线程的学习,所以本章主要介绍Thread类的核心方法。Thread类的核心方法较多,读者应该着重掌握如下技术点:

    线程的启动;

    如何使线程暂停;

    如何使线程停止;

    线程的优先级;

    线程安全相关的问题。

    以上内容也是本章学习的重点与思路,掌握这些内容是进入Java多线程学习的必经之路。

    1.1 进程和多线程概述

    本书主要介绍在Java语言中使用的多线程技术,但讲到多线程技术时不得不提及“进程”这个概念,“百度百科”对“进程”的解释如图1-1所示。

    e67444ee09244b4a7999c99822331806.png

    图1-1 进程的定义

    初看这段文字十分抽象,难以理解,那么再来看如图1-2所示的内容。

    e5de5cfd9a56c914f3eed7027b53c531.png

    图1-2 Windows 7系统中的进程列表

    难道一个正在操作系统中运行的exe程序可以理解成一个“进程”?没错!

    通过查看“Windows任务管理器”窗口中的列表,完全可以将运行在内存中的exe文件理解成进程—进程是受操作系统管理的基本运行单元。

    程序是指令序列,这些指令可以让CPU完成指定的任务。*.java程序经编译后形成*.class文件,在Windows中启动一个JVM虚拟机相当于创建了一个进程,在虚拟机中加载class文件并运行,在class文件中通过执行创建新线程的代码来执行具体的任务。创建测试用的代码如下:

    public class Test1 {

    public static void main(String[] args) {

    try {

    Thread.sleep(Integer.MAX_VALUE);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    在没有运行这个类之前,任务管理器中以“j”开头的进程列表如图1-3所示。

    d692b94c47d6acd708138489841963f7.png

    图1-3 任务管理器中以“j”开头的进程

    Test1类重复运行3次后的进程列表如图1-4所示。可以看到,在任务管理器中创建了3个javaw.exe进程,说明每执行一次main()方法就创建一个进程,其本质上就是JVM虚拟机进程。

    b2ca9fc90bb910750b8bc9ec2dfd38dd.png

    图1-4 创建了3个javaw.exe进程

    那什么是线程呢?线程可以理解为在进程中独立运行的子任务,例如,QQ.exe运行时,很多的子任务也在同时运行,如好友视频线程、下载文件线程、传输数据线程、发送表情线程等,这些不同的任务或者说功能都可以同时运行,其中每一项任务完全可以理解成是“线程”在工作,传文件、听音乐、发送图片表情等这些功能都有对应的线程在后台默默地运行。

    进程负责向操作系统申请资源。在一个进程中,多个线程可以共享进程中相同的内存或文件资源。

    fee583e023e17f62481b5c4b51432577.png

    使用多线程有什么优点呢?其实如果有使用“多任务操作系统”的经验,如Windows系列,大家应该都有这样的体会:使用多任务操作系统Windows,可以大幅利用CPU的空闲时间来处理其他任务,例如,可以一边让操作系统处理正在用打印机打印的数据,一边使用Word编辑文档。CPU在这些任务中不停地进行切换,由于切换的速度非常快,给使用者的感受是这些任务在同时运行,所以使用多线程技术可以在同一时间内执行更多不同的任务。

    为了更加有效地理解多线程的优势,下面先来看如图1-5所示的单任务运行环境。

    在图1-5中,任务1和任务2是两个完全独立、不相关的任务。任务1在等待远程服务器返回数据,以便进行后期处理,这时CPU一直呈等待状态,一直在“空运行”。任务2在10s之后被运行,虽然执行完任务2所用时间非常短,仅仅是1s,但也必须等任务1运行结束后才可以运行任务2,本程序运行在单任务环境中,所以任务2有非常长的等待时间,系统运行效率大幅降低。单任务的特点就是排队执行,即同步,就像在cmd中输入一条命令后,必须等待这条命令执行完才可以执行下一条命令。在同一时间只能执行一个任务,CPU利用率大幅降低,这就是单任务运行环境的缺点。

    多任务运行环境如图1-6所示。

    bb02d456d928c5fb1319ff35b6539edb.png

    在图1-6中,CPU完全可以在任务1和任务2之间来回切换,使任务2不必等到10s之后再运行,系统和CPU的运行效率大大提升,这就是为什么要使用多线程技术、为什么要学习多线程。多任务的特点是在同一时间可以执行多个任务,这也是多线程技术的优点。使用多线程也就是在使用异步。

    在通常情况下,单任务和多任务的实现与操作系统有关。例如,在一台计算机上使用同一个CPU,安装DOS磁盘操作系统只能实现单任务运行环境,而安装Windows操作系统则可以实现多任务运行环境。

    在什么场景下使用多线程技术?笔者总结了两点。

    1)阻塞。一旦系统中出现了阻塞现象,则可以根据实际情况来使用多线程技术提高运行效率。

    2)依赖。业务分为两个执行过程,分别是A和B。当A业务发生阻塞情况时,B业务的执行不依赖A业务的执行结果,这时可以使用多线程技术来提高运行效率;如果B业务的执行依赖A业务的执行结果,则可以不使用多线程技术,按顺序进行业务的执行。

    在实际的开发应用中,不要为了使用多线程而使用多线程,要根据实际场景决定。

    多线程是异步的,所以千万不要把Eclipse代码的顺序当作线程执行的顺序,线程被调用的时机是随机的。

    展开全文
  • 第一章 Java多线程技能 第二章 对象及变量的并发访问 第三章 线程间通信 第四章 Lock对象的使用 第五章 定时器Timer 第六章 单例模式与多线程 第七章 拾遗增补 第一章 Java多线程技能 1. 单任务的特点是排队执行。 ...

    第一章 Java多线程技能
    第二章 对象及变量的并发访问
    第三章 线程间通信
    第四章 Lock对象的使用
    第五章 定时器Timer
    第六章 单例模式与多线程
    第七章 拾遗增补

    第一章 Java多线程技能

    1. 单任务的特点是排队执行。

    单任务是一个命令执行完才能执行下一个任务
    

    2. 多任务是同一时间可以执行多个任务

    任务之间可以来回切换,系统和CPU的运行效率大大提升
    

    3. 多线程也就是在使用异步(多线程是异步的)

    4. 实现多线程有两种方式:继承Thread类和实现Runnable接口

    5. 线程的优先级具有继承性和传递性

    可以通过setPriority()方法设置优先级
    优先级范围:1 ~ 10
    

    6. sleep()

    Thread.sleep(millis) 当使用这个方法的时候可以运行其他线程
    

    7. start() 和 run()

    当运行---.start()的时候,会自动启动---.run() 方法
    线程中使用---.start() 是跳到---线程,若使用---.run() 使用的还是当前线程
    

    8. Thread.currentThread().getName() 方法和this.getName()

    Thread.currentThread().getName() 目前正在执行这条语句的线程名
    this.getName()  创建这个对象得线程名(一般为默认的)
    

    9. 判断线程是否处于中断状态

    this.interrupted()  测试当前所在线程是否中断(第一次判断后会,中断状态会清除)
    this.isInterrupted() 测试的是这个this线程是否已经终端
    

    10. synchronized关键字

    此关键字可以对任意对象及方法加锁,加锁这段代码称之为"互斥区"或"临界区"
    

    11. println方法

    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    此方法内部也加了锁,所以当使用---.suspend() 暂停的时候没如果正在进行输出活动,可能会锁在里面出不开
    

    12. yield() 方法

    作用:放弃当前的CPU资源.
    

    第二章 对象及变量的并发访问

    1. 方法内的变量为线程安全的

    两个线程使用同一个类的时候,类中的方法中的局部变量是线程安全的,因为方法内部的变量具有私有特性
    

    2. 关键字synchronized的锁都是对象锁不是锁定方法

    3. 调用关键字synchronized声明的方法一定是排队运行的

    4. 同一个对象中的不同方法

    如果其中有一个synchronized或者没有的话,可以异步调用两个方法
    如果两个方法都有synchronized修饰的话,只能一个一个排队等待,也就是同步
    

    5. 脏读

    发生脏读的原因: 当读取实例变量时,此值已经被其他线程更改过了。
    脏读的解决:也是通过synchronized修饰方法解决的。
    

    6. synchronized锁重入

    解读:一个对象调用了一个synchronized修饰的方法,此时这个对象锁还没有释放,还可以获得其他synchronized修饰的方法。
    锁重入支持父子类继承:当存在父子关系时(extends),子类完全可以通过锁重入调用父类的同步方法
    

    7. 当出现异常的时候,锁可以自动释放

    8. suspend()和sleep(millis)方法被调用后并不释放锁

    9. 重写的方法(extends)如果没加synchronized,视为异步

    父类使用了synchronized修饰方法,子类重写的时候没有添加synchronized修饰该方法,视为可以异步调用
    

    10. public static boolean holdsLock(Boject obj)

    System.out.println("A " + Thread.currentThread().holdsLock(Test.class));
    synchronized(Test.class) {
        System.out.println("B " + Thread.currentThread().holdsLock(Test.class));
    }
    System.out.println("C " + Thread.currentThread().holdsLock(Test.class));
    输出 A false       B true      C false
    当currentThread在指定的对象上保持锁定时,才返回true
    

    11. 一半异步,一半同步

    想要计算的内容可以让它异步,想输出的内容可以使用同步代码块synchronized(this){} 输出,这样可以做到一半同步,一半异步。
    

    12. synchronized代码块具有同步性

    当线程访问object的一个synchronized(this)同步代码块的时候,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞。
    

    13. println()方法也是同步的

    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    

    14. synchronized(this) 也是锁定当前对象的

    synchronized(this)也是锁定的当前对象,但是可以访问异步访问当前对象其他没有被synchronized修饰的方法。
    

    15. synchronized同步方法和synchronized(this)同步代码块的作用

    1. 对其他synchronized同步方法或者synchronized(this)同步代码块调用呈同步效果
    2. 同一时间只有一个线程可以执行synchronized同步方法/synchronized(this)同步代码块中的代码
    

    16. synchronized(非this对象x)同步代码块的作用

    当多个线程争抢相同的"非this对象x"的锁时,同一时间只有一个线程可以执行synchronized(非this对象x)同步代码块中的代码
    注意:当非this对象x位于方法内(也就是局部变量)的时候,多个锁就是异步执行
    

    17. 三个结论

    当多个线程同时执行synchronized(x){}同步代码时呈同步效果
    当其他线程执行x对象中synchronized同步方法时呈同步效果
    当其他线程执行x对象方法里面的synchronized(this)代码块呈现同步效果
    

    18. 每一个*.java文件对应Class类的实例都是一个,在内存中是单例的

    19. 静态同步synchronized方法与synchronized(class)代码块

    synchronized关键字加到static静态方法上的方式是将Class类对象作为锁,而synchronized关键字加到非static静态对象上的方式时间将方法所在类的对象作为锁
    

    20. 同步syn static方法可以对类的所有对象实例起作用

    21. 同步syn(class)代码块可以对类的所有实例起作用

    同步syn static方法其实和同步syn(class)代码块的作用是一样的(synchronized(类.class))
    

    22. 可以使用同步块来解决synchronized方法无限等待问题

    23. 多线程死锁

    死锁是程序设计的Bug,在设计程序时要避免双方互相持有对方的锁,只要互相等待对方的释放锁,就有可能出现死锁
    

    24. 所对象改变导致异步执行

    synchronized(对象)
    

    25. volatile关键字

    三种特性:可见性,原子性,进制代码重排序
    只能修饰变量
    可见性:指A线程更改变量的值后,B线程立马能看待更改过后的值
    

    26. synchronized关键字也具有volatile关键字的三个特性

    第三章 线程间通信

    1. wait/notify机制的原理

    wait()方法的作用是使当前执行wait()方法的线程等待,在此处所在的代码暂停执行,并释放锁,知道接到通知或者终端为止。
    notify()方法用来通知那些可能等待的锁,如果有多个线程等待,则根据执行wait()方法的顺序发出通知,并使该线程重新获得锁,执行notify()方法后,并不是当前线程马上释放改锁,直到退出synchronized同步区域后,当前线程才会释放锁,而呈wait状态的线程才可以获得该对象锁
    只能在同步方法中嗲欧总wait()方法和notify()方法
    

    2. notiftAll()方法

    按照执行wait()方法相反的顺序依次唤醒全部的线程
    

    3. 关于notify()方法和notifyAll()方法

    不是所有的JVM在执行notify()都是按照wait()方法的正序进行唤醒的,也不是所有的JVM在执行notifyAll()都是按照wait()方法的倒叙序进行唤醒的,具体的唤醒顺序依赖JVM的具体实现
    

    4. wait(long)方法

    带一个参数的此方法的功能是等待某一段时间内是否有线程对锁进行notify()通知唤醒,如果超过这个时间点则线程会自动唤醒,能继续向下运行的前提是再次持有锁。
    

    5. 假死

    就是全部线程都进出wait()状态,出现假死状态很大的可能是唤醒了同类
    

    6. 实现任意数量的几对几生产与消费

    使用while结合notifyAll()的方法,这种组合具有通用性
    

    7. 通过管道进行线程间通信—字节流

    字节流用到的类有PipedInputStream和PipedOutputStream
    字符流用到的类有PipedReader和PipedWriter
    

    8. join()方法的使用

    join()方法的作用是使所属的线程对象x正常执行run()方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后执行z后面的代码,具有串联执行的效果
    注意:join()方法和interrupt()方法如果彼此遇到,则出现异常
    x.join(long)方法中的参数用于设定等待的时间,不管x线程是否执行完毕,时间到了并且重新获得锁,则当前线程会继续向后运行,如果没有重新获得锁,则一直在尝试
    

    9. join(long)方法和sleep(long)方法的区别

    join(long)方法的内部是使用的wait(long)方法来进行实现的,说明会释放锁,而sleep(long)不会 释放锁
    

    10. 使用InheritableThreadLoval可使子线程继承父线程的值

    11. 通过重写childValue()方法,子线程可以对父线程继承的值进行修改

    通过InheritableThreadLocalExe.set()方法和childValue()都可以对值进行修改,区别:InheritableThreadLocalExe.set()方法可以任意时刻进行修改,而重写childValue()方法实现子线程具有最新值是只有在创建子线程是才会发生,但是仅仅是一次
    

    第四章 Lock对象的使用

    1. 使用ReentrantLock对象可以实现同步

    调用ReentrantLock对象的lock()锁可以获取锁,调用unlock()方法释放锁,这两个方法成对出现,要想实现一些代码的同步,可以把这些代码放在这两个方法之间
    

    2. Condition对象

    Condition对象的作用是控制并处理线程的状态。
    

    3. await()方法

    await()方法的作用使当前线程在接到通知或被中断之前一直处于wait状态,他和wait()的作用是一样的
    注意:在调用---await()方法之前需要先获得锁lock.lock()
    

    4. 使用await()方法和signal()实现wait()/notify机制

    Object类中的wait()方法相当于Condition类中的await()方法
    Object类中的wait(long timeout)方法相当于Condition类中的await(long time,TimeUnit unit)方法
    Object类中的notify()方法相当于Condition类中的signal()方法
    Object类中的notifyAll()方法相当于Condition类中的signalAll()方法
    

    5. await()方法实现暂停效果的原理

    内部使用了UNSAFE.park(false, 0L)
    

    6. 唤醒部分线程的方法

    Condition对象可以唤醒部分指定线程,可以对线程进行分组,然后唤醒指定组中的线程
    

    7. 公平锁和非公平锁

    公平锁:采用先到先得的策略,每次获取锁之前都会检查队列里面有没有排队等待的线程,没有才会尝试获取锁,如果有就将当前线程追加到队列中
    非公平锁:采用“有机会插队”的策略,一个线程获取锁之前先去尝试获取锁而不是在排队中等待,如果获取锁成功,说明线程虽然是后启动的,但先获得了锁,这就是“作弊插队的效果。
    

    8. getHoldCount()方法是查询当前线程保持此锁定的个数,也就是调用lock()的次数

    9. getQueueLength()方法的使用

    返回整等待获取此锁的线程估计数
    

    10. getWaitQueueLength(Condition)方法的使用

    返回等待与此锁相关的给定条件Condition的线程估计数,也就是返回有多少个线程执行了condition对象中的await()方法而呈等待状态
    

    11. hasQueuedThread(Thread)方法的使用

    查询指定的线程是否正在等待获取此锁,也就是判断参数中的线程是否在等待队列中
    

    12. hasQueueThreads() 方法的使用

    查询是够有线程正在等待获取此锁,也就是等待队列中是否有等待线程
    

    13. hasWaiters(Condition)方法的使用

    查询是否有线程正在等待与此锁有关的condition条件,也就是是否有线程执行了condition对象中的await()方法而呈等待状态
    

    14. isFair()方法的使用

    判断是不是公平锁
    

    15. 默认状态下ReentrantLock类使用的是非公平锁

    16. isHeldByCurrentThread()方法的使用

    查询当前线程是否保持此锁
    

    17. isLocked()方法的使用

    查询此锁是否由任意线程保持并没有释放
    

    18. lockInterruptibly()方法的使用

    当某个线程尝试获取锁并且阻塞在lockInterruptibly()方法时,该线程可以被中断
    

    19. tryLock()方法的使用

    嗅探拿锁,如果当前线程发现锁在被其他线程持有,则返回false,程序继续执行后面的代码,而不是呈阻塞等待锁的状态
    

    20. tryLock(long timeout, Timeunit unit)方法的使用

    如果当前线程在指定的timeout内持有了锁,则返回true,超过时间则返回false,参数timeout代表当前线程抢锁的时间
    

    21. await(long time, TimeUnit unit)方法的使用

    作用和wait(long timeout)方法的作用一样,都具有唤醒线程的功能
    

    22. awaitNanos(long nanosTimeout)方法的使用

    和wait(long timeout)的作用一样,都具有唤醒线程的功能,时间单位是纳秒(ns)
    

    23. awaitUntil(Date deadline)方法的使用

    指定的Date结束等待
    

    24. awaitUninterruptibly()方法的使用

    实现线程在等待的过程中,不允许被打断
    await()方法是可以被打断的
    

    25. 使用ReentrantReadWriteLock类(这是一种读写锁)(读锁之间可以共享)

    读写锁有两个锁:一个是读操作相关的锁,也称为共享锁;另一个是写操作相关的锁,也称为排他锁
    注意:读锁之间不互斥,读锁和写锁互斥,写锁和写锁互斥,因此只要出现写锁,就会出现互斥同步的效果
    1. ReentrantLock类与ReentrantReadWriteLock类相比,ReentrantLock类的主要缺点是使用ReentrantLock对象时,所有的操作都同步,哪怕只是对实例变量的读操作。
    2. 总结:读写互斥,写读互斥,谢谢互斥,读读异步
    

    第五章 定时器Timer

    1. 定时器Timer的使用

    1. Timer类的主要作用是设置计划任务
    2. TimerTask类的主要作用是封装任务
    3. 执行计划任务的代码要放入TimerTask的子类中,因为TImerTask是一个抽象类
    

    2. schedule(TimerTask task, Date time)方法的测试

    
    

    3. 使用public void cancel()方法可以实现线程TImerThread销毁

    作用:终止此计时器,丢弃所有当前已安排的任务,这不会干扰当前正在执行的任务(如果存在)
    ※ 可以重复调用此方法,但是第二次和后续调用无效
    

    4. 如果执行任务的时间早于当前时间,则立刻执行task任务

    5. schedule(TimerTask task, Date firstTime, long period)方法

    作用:指定日期之后按指定的间隔周期无线循环地执行某一任务
    

    6. Timer类的cancel()方法

    和 TImerTask类中的cancel()方法清除自身不同,Timer类中的cancel方法的作用是将任务队列中的全部任务清空
    

    7. Timer类中的cancel()方法并不一定会停止计划任务

    原因:Timer中的cancel()方法有事并没有正抢到queue锁
    

    8. schedule(TimerTask task, long delay)方法

    以当前时间为参考,在此时间的基础上延迟指定的毫秒数后执行一次TimerTask任务
    

    9. schedule(TimerTask task, long delay, long period)方法

    在此时间的基础上延迟指定的毫秒数再以某一间隔时间无限次数地执行某一任务
    

    10. 任务的延时和不延时

    任务的不延时:第一次执行任务的时间是任务的开始时间加上delay时间,接下来执行任务的时间是上一次任务的开始时间加上period时间
    任务延时:下一次任务的执行时间参考上一次任务"结束"时的时间来开始的
    

    11. scheduleAtFixedRate()方法和schedule()方法的区别

    scheduleAtFixedRate()方法具有追赶型
    比如我任务开始的时间早于当前时间,schedule()方法会在当前时间进行线程计时运行,但是scheduleAtFixedRate()方法会先追平(弥补)回来,再从当前点接着执行
    

    第六章 单例模式与多线程

    1. 立即加载/饿汉模式

    public classs MyObject{
        private static MyObject myobject = new MyObject();
        private MyObject(){}
        public static MyObject getInstance() {
            return MyObject;
        }
    }
    ※ 此版本为立即加载型,但此版本代码的缺点是不能有其他实例变量,因为getInstance()方法没有同步,所以有可能出现非线程安全问题
    

    2. 延迟加载/懒汉模式

    public classs MyObject{
        private static MyObject myobject;
        private MyObject(){}
        public static MyObject getInstance() {
            if(myobject != null) {
            } else {
                myobject = new MyObject();
            }
           return myobject;
        }
    }
    缺点:多线程环境下会出现“错误的单例”创建出“多例”的情况
    

    3. DCL机制(Double-Check Locking, 双检查锁)

    DCL机制是大多数对县城结合单例模式使用的解决方案
    ※ 使用volatile修饰变量使该变量在多个线程间达到可见性,另外也禁止了初始化的时候的代码重排序
    

    4. 使用静态内置类实现单例模式

    public class MyObject {
        private static class MyObjectHandler {
            private static MyObject myObject = new MyObject();
        }
        private MyObject(){}
        public static MyObject getInstance() {
            return MyObjectHandler.myObject;
        }
    }
    

    5. 使用static代码块实现单例模式

    public class MyObject {
        private static MyObject instance = null;
        private MyObject(){}
        static {
            instance = new MyObject();
        }
        public static MyObject getInstance() {
            return instance;
        }
    }
    

    6. 使用enum枚举数据类型实现单例模式

    第七章 拾遗增补

    1. 线程的状态

    NEW: 线程实例化后还未执行start()方法
    RUNNABLE状态下,线程进入运行状态
    TERMINATED状态下,线程被销毁了
    TIMED_WAITING状态下,代表线程执行了Thread.sleep()方法,呈等待状态
    BLOCKED状态是某个线程在等待锁的时候
    WAITING状态是线程执行了Object.wait()方法后的状态
    

    2. 线程组

    线程对象关联线程组:一级关联: 就是父对象中有子对象,但并不创建子孙对象
    线程对象关联线程组:多级关联:就是父对象中有个子对象,子对象中再创建子对象,即子孙对象
    可以实现多级关联的关键代码是ThreadGroup类的构造方法
    ※ 在实例化一个ThreadGroup线程组x时,如果不指定所属的线程组,则x自动归属到当前线程对象所属的线程组中
    ※ 通过把线程归属到线程组中,当调用线程组ThreadGroup的interrupt()方法时可以中断该组中所有正在运行的线程
    

    3. activeGroupCount() 方法

    取得子孙组的数量
    

    4. Thread.activeCount()方法

    返回当前线程的线程组中活动线程的数量
    

    5. Thread.enumerate(Thread tarray[])方法的使用

    Thread.enumerate(Thread tarray[])方法的作用是将当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中。
    
    展开全文
  •     在前面的博客中简单实现了Android单线程断点下载以及Android文件多线程下载,这篇将实现多线程断点下载。对于断点下载,我们知道主要是为了实现不重复下载上次下载过的数据文件内容,而和前面实践的区别在于...
  • Java线程及多线程技术及应用 第6 章 Java线程及多线程技术及应用 6.1线程基本概念 1、进程和线程的基础知识 l 进程:运行中的应用程序称为进程,拥有系统资源(cpu、内存) l 线程:进程中的一段代码,一个进程中可以...
  • 多线程下载介绍多线程下载技术是很常见的一种下载方案,这种方式充分利用了多线程的优势,在同一时间段内通过多个线程发起下载请求,将需要下载的数据分割成多个部分,每一个线程只负责下载其中一个部分,然后将下载...
  • Java 多线程技术

    2021-01-07 20:41:09
    多线程 文章目录多线程1 概述1.1 线程与进程1.1.1 进程1.1.2 线程1.2 线程调度1.2.1 分时调度1.2.2 抢占式调度1.3 同步与异步1.4 并发与并行2 在Java中启用多线程2.1 继承Tread类2.2 实现Runnable接口2.3 继承Thread...
  • 在进行数据上传的时候可能是多线程操作,很多图像数据同时做上传或者单一的图像,如果图像比较多或者单一图像数据比较大,自然不希望失败一次或者暂停一次之后完全重传,有断点续传功能可以节省网络流量和节省用户...
  • 【转】什么是线程安全?怎么实现线程安全? 什么是进程? 什么是线程? 什么是线程安全? 添加一个状态呢?...如何确保线程安全?...提到多线程这里要说两个概念,就是串行和并行,搞清楚这个,我们才能更
  • 分片下载所谓分片下载就是要利用多线程的优势,将要下载的文件一块一块的分配到各个线程中去下载,这样就极大的提高了下载速度。技术难点并不能说是什么难点,只能说没接触过不知道罢了。1、如何请求才能拿到数据的...
  • 【python学习】多线程下载图片实战

    千次阅读 2021-06-09 11:20:55
    python多线程下载图片(setu) 前言 python的学习其实早在两三个星期前就开始了,奈何我是个急性子,所以学的很浮躁,甚至连md笔记都没写。但是想了想,我学python的目的反正也仅仅是为了ctf的比赛。所以我直接去...
  • 一、高并发系统接受实现多用户多请求的高并发时,通过多线程来实现。二、线程后台处理大任务一个程序是线性执行的。如果程序执行到要花大量时间处理的任务时,那主程序就得等待其执行完才能继续执行下面的。那用户就...
  • 提高下载速度有几种方法。1.多线程。...给个以前我用的伪代码import concurrentfrom concurrent.futures import ThreadPoolExecutordef download_all_articles(list_page_urls):# 多线程下载器works = le...
  •   日常工作中,大家应该经常遇到要下载资源的场景,下载资源时,有时网络很给力,一会儿就下载成功了,有时下载很慢,几十分钟后都还在下载中,甚至更过分的是下载好长时间后直接来个下载失败。好不惹人生气。 当...
  • Java多线程下载器 https://github.com/yoyling/JDownloader/archive/refs/heads/master.zip 五一无聊搞出来的,虽然已存在IDM、XDM这种多线程下载工具了,实现了很多功能了。 基于对技术的执著,自己也动手写个,...
  • Java 多线程1

    2021-02-28 06:43:24
    进程——进入内存运行的程序线程——进程的执行单元程序被执行时,main主线程必定被执行,如果该程序被设计为多线程,则其它线程也将被运行一个程序中有多个线程在同时执行“迅雷”程序具有下载功能 迅雷软件被双击...
  • 多线程PPT

    2021-03-13 20:29:28
    多线程的优缺点多线程的优点能适当提高程序的执行效率能适当提高资源利用率(CPU、内存利用率)多线程的缺点创建线程是有开销的,iOS下主要成本包括:内核数据结构(大约1KB)、栈空间(子线程512KB、主线程1MB,也可以...
  • 多线程、线程池、并发包每当谈起这些词汇,可能不是在面试就是在准备面试的路上了。有句话叫“面试造航母,工作拧螺丝“,确实很多情况下我们是用不到这些东西的,但是学好这些东西对我们的日常工作也可能会产生...
  • Java多线程

    2021-03-01 06:25:03
    1. 多线程image.png新建状态: 一个新产生的线程从新状态开始了它的生命周期。它保持这个状态直到程序 start 这个线程。运行状态:当一个新状态的线程被 start 以后,线程就变成可运行状态,一个线程在此状态下被认为...
  • Java多线程技能

    2021-03-01 08:14:53
    下面进入Java多线程的学习,首先介绍Thread类的核心方法* 线程的启动* 线程的暂停* 线程停止* 线程的优先级* 线程安全的相关问题一、进程要学习多线程就不得不提到进程,进程是什么,当我们打开windows系统的任务...
  • CPU核心单元组 他只是整个CPU的一部分,并不能称它为CPU,它负责逻辑运算,是最重要的一部分。 CPU CPU是CPU核心单元组(逻辑处理单元),时钟...技术进步后一个CPU上可以有个CPU核心单元组(逻辑处理单元)。此时
  • 最近在研究Spring Boot中的异步处理,发现涉及到异步和多线程的很多知识点,就先写几篇关于异步与多线程的文章,带大一起回顾或学习一下相关的知识点。下面开始正文内容: 前言 在本文中,我们通过一些通俗易懂的...
  • Mac os 多线程

    2021-01-20 20:25:09
    多线程的原理: 同一时间,CPU只能处理1条线程,只有1条线程在工作(执行) 多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换) 如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象 如果...
  • 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。着重点的话,就是最后一句进程是程序的实体,个人理解的话,也可以认为是进程就...
  • 这个时候就应该利用多线程技术,将耗时任务的代码放到一个新的线程中运行,同时向主程序线程更新进度。 接下来我用Qt中QThread来实现这个目的。 我用的编程环境是Visual Studio 2019 Community和Qt 5.12。 主界面 在...
  • 图文并茂 通俗易懂日本资-深技术作家、《程序员的数学》作者结城浩执笔,264张图表(UML类图、时序图、Timethreads图等)穿插文中,通过类比手法和浅显的语言,逐一讲解与多线程和并发处理相关的12种设计模式。...
  • 关于Python中的多线程 一、概念介绍 什么是线程、多线程 线程(Thread)也叫轻量级进程(注:进程是正在进行的一个过程或者一个任务,计算机中运行的应用程序即可理解为一个进程),线程被包含在进程中,它是进程中的实际...
  • IDM这款软件非常火,很多人都会拿它,跟迅雷进行比较。这几年来,迅雷的口碑不太好,软件内置大量广告不说,不开通会员速度也不稳定...这是一款非常经典的多线程下载软件,它的HTTP下载功能,堪称神器。它的界面虽然老
  • Java多线程的应用总结

    2021-03-05 16:44:56
    下载文件,浏览网站时加载图片,通过多线程就可以实现多文件下载,一下做好几个工作,这样效率更高,线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 162,673
精华内容 65,069
关键字:

多线程下载技术