精华内容
下载资源
问答
  • Java多线程之初识线程

    万次阅读 2020-09-10 23:49:26
    文章目录实现多线程的两种方式区别继承Thread示例实现Runnable接口示例start()的执行步骤 实现多线程的两种方式 1、继承Thread类; 2、实现Runnable接口。 区别 Java语言是单继承的,使用实现Runnable方式创建线程,...

    实现多线程的两种方式

    1、继承Thread类;

    2、实现Runnable接口。

    区别

    Java语言是单继承的,使用实现Runnable方式创建线程,可以实现多继承。

    继承Thread示例

    public class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            System.out.println("MyThread");
        }
    }
    
    public class Run {
        public static void main(String[] args) {
            MyThread myThread = new MyThread();
            myThread.start();
            System.out.println("End.");
        }
    }
    
    输出结果:
    End.
    MyThread
    

    实现Runnable接口示例

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("MyThread");
        }
    }
    
    public class Run {
        public static void main(String[] args) {
            MyRunnable runnable = new MyRunnable();
            Thread myThread = new Thread(runnable);
            myThread.start();
            System.out.println("End.");
        }
    }
    
    输出结果:
    End.
    MyThread
    

    start()方法比较耗时,导致“End.”会先输出。

    start()的执行步骤

    1、通过JVM告诉操作系统创建Thread。

    2、操作系统开辟内存并使用Windows SDK中的createThread()函数创建Thread线程对象。

    3、操作系统对Thread对象进行调度,以确定执行时机。

    4、Thread在操作系统中被成功执行。

    展开全文
  • Java 多线程:彻底搞懂线程池

    万次阅读 多人点赞 2019-07-09 19:27:00
    熟悉Java多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了。 目录 1 线程池的优势 2 线程池的使用 3 线程池的工作原理 4 线程池的参数 4.1 任务队列...

    熟悉 Java 多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了。

    目录

    1 线程池的优势

    2 线程池的使用

    3 线程池的工作原理

    4 线程池的参数

    4.1 任务队列(workQueue)

    4.2 线程工厂(threadFactory)

    4.3 拒绝策略(handler)

    5 功能线程池

    5.1 定长线程池(FixedThreadPool)

    5.2 定时线程池(ScheduledThreadPool )

    5.3 可缓存线程池(CachedThreadPool)

    5.4 单线程化线程池(SingleThreadExecutor)

    5.5 对比

    6 总结

    参考


    1 线程池的优势

    总体来说,线程池有如下的优势:

    (1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

    (2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。

    (3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

    2 线程池的使用

    线程池的真正实现类是 ThreadPoolExecutor,其构造方法有如下4种:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }
    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }
    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

    可以看到,其需要如下几个参数:

    • corePoolSize(必需):核心线程数。默认情况下,核心线程会一直存活,但是当将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。
    • maximumPoolSize(必需):线程池所能容纳的最大线程数。当活跃线程数达到该数值后,后续的新任务将会阻塞。
    • keepAliveTime(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。
    • unit(必需):指定 keepAliveTime 参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
    • workQueue(必需):任务队列。通过线程池的 execute() 方法提交的 Runnable 对象将存储在该参数中。其采用阻塞队列实现。
    • threadFactory(可选):线程工厂。用于指定为线程池创建新线程的方式。
    • handler(可选):拒绝策略。当达到最大线程数时需要执行的饱和策略。

    线程池的使用流程如下:

    // 创建线程池
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE,
                                                 MAXIMUM_POOL_SIZE,
                                                 KEEP_ALIVE,
                                                 TimeUnit.SECONDS,
                                                 sPoolWorkQueue,
                                                 sThreadFactory);
    // 向线程池提交任务
    threadPool.execute(new Runnable() {
        @Override
        public void run() {
            ... // 线程执行的任务
        }
    });
    // 关闭线程池
    threadPool.shutdown(); // 设置线程池的状态为SHUTDOWN,然后中断所有没有正在执行任务的线程
    threadPool.shutdownNow(); // 设置线程池的状态为 STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表

    3 线程池的工作原理

    下面来描述一下线程池工作的原理,同时对上面的参数有一个更深的了解。其工作原理流程图如下:

    通过上图,相信大家已经对所有参数有个了解了。下面再对任务队列、线程工厂和拒绝策略做更多的说明。

    4 线程池的参数

    4.1 任务队列(workQueue)

    任务队列是基于阻塞队列实现的,即采用生产者消费者模式,在 Java 中需要实现 BlockingQueue 接口。但 Java 已经为我们提供了 7 种阻塞队列的实现:

    1. ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列(数组结构可配合指针实现一个环形队列)。
    2. LinkedBlockingQueue: 一个由链表结构组成的有界阻塞队列,在未指明容量时,容量默认为 Integer.MAX_VALUE
    3. PriorityBlockingQueue: 一个支持优先级排序的无界阻塞队列,对元素没有要求,可以实现 Comparable 接口也可以提供 Comparator 来对队列中的元素进行比较。跟时间没有任何关系,仅仅是按照优先级取任务。
    4. DelayQueue:类似于PriorityBlockingQueue,是二叉堆实现的无界优先级阻塞队列。要求元素都实现 Delayed 接口,通过执行时延从队列中提取任务,时间没到任务取不出来。
    5. SynchronousQueue: 一个不存储元素的阻塞队列,消费者线程调用 take() 方法的时候就会发生阻塞,直到有一个生产者线程生产了一个元素,消费者线程就可以拿到这个元素并返回;生产者线程调用 put() 方法的时候也会发生阻塞,直到有一个消费者线程消费了一个元素,生产者才会返回。
    6. LinkedBlockingDeque: 使用双向队列实现的有界双端阻塞队列。双端意味着可以像普通队列一样 FIFO(先进先出),也可以像栈一样 FILO(先进后出)。
    7. LinkedTransferQueue: 它是ConcurrentLinkedQueueLinkedBlockingQueue 和 SynchronousQueue 的结合体,但是把它用在 ThreadPoolExecutor 中,和 LinkedBlockingQueue 行为一致,但是是无界的阻塞队列。

    注意有界队列和无界队列的区别:如果使用有界队列,当队列饱和时并超过最大线程数时就会执行拒绝策略;而如果使用无界队列,因为任务队列永远都可以添加任务,所以设置 maximumPoolSize 没有任何意义。

    4.2 线程工厂(threadFactory)

    线程工厂指定创建线程的方式,需要实现 ThreadFactory 接口,并实现 newThread(Runnable r) 方法。该参数可以不用指定,Executors 框架已经为我们实现了一个默认的线程工厂:

    /**
     * The default thread factory.
     */
    private static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;
    
        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }
    
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }

    4.3 拒绝策略(handler)

    当线程池的线程数达到最大线程数时,需要执行拒绝策略。拒绝策略需要实现 RejectedExecutionHandler 接口,并实现 rejectedExecution(Runnable r, ThreadPoolExecutor executor) 方法。不过 Executors 框架已经为我们实现了 4 种拒绝策略:

    1. AbortPolicy(默认):丢弃任务并抛出 RejectedExecutionException 异常。
    2. CallerRunsPolicy:由调用线程处理该任务。
    3. DiscardPolicy:丢弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。
    4. DiscardOldestPolicy:丢弃队列最早的未处理任务,然后重新尝试执行任务。

    5 功能线程池

    嫌上面使用线程池的方法太麻烦?其实Executors已经为我们封装好了 4 种常见的功能线程池,如下:

    • 定长线程池(FixedThreadPool)
    • 定时线程池(ScheduledThreadPool )
    • 可缓存线程池(CachedThreadPool)
    • 单线程化线程池(SingleThreadExecutor)

    5.1 定长线程池(FixedThreadPool)

    创建方法的源码:

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    }
    • 特点:只有核心线程,线程数量固定,执行完立即回收,任务队列为链表结构的有界队列。
    • 应用场景:控制线程最大并发数。

    使用示例:

    // 1. 创建定长线程池对象 & 设置线程池线程数量固定为3
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
    // 2. 创建好Runnable类线程对象 & 需执行的任务
    Runnable task =new Runnable(){
      public void run() {
         System.out.println("执行任务啦");
      }
    };
    // 3. 向线程池提交任务
    fixedThreadPool.execute(task);

    5.2 定时线程池(ScheduledThreadPool )

    创建方法的源码:

    private static final long DEFAULT_KEEPALIVE_MILLIS = 10L;
    
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }
    
    public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }
    public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue(), threadFactory);
    }
    • 特点:核心线程数量固定,非核心线程数量无限,执行完闲置 10ms 后回收,任务队列为延时阻塞队列。
    • 应用场景:执行定时或周期性的任务。

    使用示例:

    // 1. 创建 定时线程池对象 & 设置线程池线程数量固定为5
    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
    // 2. 创建好Runnable类线程对象 & 需执行的任务
    Runnable task =new Runnable(){
      public void run() {
         System.out.println("执行任务啦");
      }
    };
    // 3. 向线程池提交任务
    scheduledThreadPool.schedule(task, 1, TimeUnit.SECONDS); // 延迟1s后执行任务
    scheduledThreadPool.scheduleAtFixedRate(task,10,1000,TimeUnit.MILLISECONDS);// 延迟10ms后、每隔1000ms执行任务

    5.3 可缓存线程池(CachedThreadPool)

    创建方法的源码:

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }
    • 特点:无核心线程,非核心线程数量无限,执行完闲置 60s 后回收,任务队列为不存储元素的阻塞队列。
    • 应用场景:执行大量、耗时少的任务。

    使用示例:

    // 1. 创建可缓存线程池对象
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    // 2. 创建好Runnable类线程对象 & 需执行的任务
    Runnable task =new Runnable(){
      public void run() {
         System.out.println("执行任务啦");
      }
    };
    // 3. 向线程池提交任务
    cachedThreadPool.execute(task);

    5.4 单线程化线程池(SingleThreadExecutor)

    创建方法的源码:

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    threadFactory));
    }
    • 特点:只有 1 个核心线程,无非核心线程,执行完立即回收,任务队列为链表结构的有界队列。
    • 应用场景:不适合并发但可能引起 IO 阻塞性及影响 UI 线程响应的操作,如数据库操作、文件操作等。

    使用示例:

    // 1. 创建单线程化线程池
    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    // 2. 创建好Runnable类线程对象 & 需执行的任务
    Runnable task =new Runnable(){
      public void run() {
         System.out.println("执行任务啦");
      }
    };
    // 3. 向线程池提交任务
    singleThreadExecutor.execute(task);

    5.5 对比

    6 总结

    Executors 的 4 个功能线程池虽然方便,但现在已经不建议使用了,而是建议直接通过使用 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

    其实 Executors 的 4 个功能线程有如下弊端:

    • FixedThreadPool 和 SingleThreadExecutor:主要问题是堆积的请求处理队列均采用 LinkedBlockingQueue,可能会耗费非常大的内存,甚至 OOM。
    • CachedThreadPool 和 ScheduledThreadPool:主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

     

    参考

     

    展开全文
  • Java多线程03_线程状态、优先级、用户线程和守护线程 线程方法: setPriority() 更改线程优先级 static void sleep() 线程休眠 void join() 插队 static void yield() 礼让 void interrupt() 中断...

    Java多线程03_线程状态、优先级、用户线程和守护线程


    在这里插入图片描述


    线程方法:

    setPriority()				更改线程优先级
    static void sleep()			线程休眠
    void join()					插队
    static void yield()			礼让
    void interrupt()			中断线程
    boolean isAlive()			是否存活
    

    停止线程:

    不推荐JDK提供的stop()、destory()方法 【已废弃】

    推荐让线程正常停止,不要死循环!

    建议使用一个标志位进行终止,当flag=false,则终止线程运行

    public class TestStop implements Runnable{
    
    	private boolean flag = true;
    	
    	@Override
    	public void run() {
    		int i = 0;
    		while(flag) {
    			System.out.println("run...Thread"+i++);
    		}
    	}
    	
    	//设置公开方法利用标志位停止线程
    	public void stopThread() {
    		this.flag = false;
    		System.out.println("线程停止了");
    	}
    	
    	public static void main(String[] args) {
    		TestStop testStop = new TestStop();
    		new Thread(testStop).start();
    		
    		for(int i=0;i<1000;i++) {
    			System.out.println("main...,"+i);
    			if(i==900) {
    				testStop.stopThread();
    			}
    		}
    		
    	}
    	
    }
    

    线程休眠:

    sleep方法存在异常:InterruptedException

    sleep时间结束,线程进入就绪状态

    每个对象都有一个锁,sleep不会释放锁

    Thread.sleep(1000);
    

    线程礼让:

    让当前执行的线程暂停,但不阻塞

    将线程从运行状态转为就绪状态

    礼让不一定成功,看cpu心情

    Thread.yield();
    

    Join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞(插队)

    main线程和Thread线程交替执行,当main线程执行到200时,Thread线程插队,一直到执行结束,main线程才能重新执行

    package com.blu.demo1;
    
    public class TestJoin implements Runnable{
    
    	@Override
    	public void run() {
    		for(int i = 0;i < 1000;i++) {
    			System.out.println("vip线程正在执行....."+i);
    		}
    	}
    	
    	public static void main(String[] args) throws InterruptedException {
    		TestJoin testJoin = new TestJoin();
    		Thread thread = new Thread(testJoin);
    		thread.start();
    		
    		for(int i = 0;i < 1000;i++) {
    			if(i==200) {
    				thread.join();
    			}
    			System.out.println("main线程正在执行....."+i);
    		}
    	}
    
    }
    

    getState()监测线程状态:

    返回枚举类型:

    NEW	
    RUNNABLE
    BLOCKED
    WAITING
    TIMED_WAITING
    TERMINATED
    

    线程优先级:

    线程优先级用1-10之间的整数表示,1为最低优先级,10为最高优先级

    主线程优先级默认为5,且不可修改

    枚举
    Thread.MAX_PRIORITY = 10
    Thread.NORM_PRIORITY = 5
    Thread.MIN_PRIORITY = 1

    优先级高不一定先执行,由CPU调度决定

    public class TestPriority {
    	
    	public static void main(String[] args) {
    		//主线程优先级
    		System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
    		MyPriority myPriority = new MyPriority();
    		Thread t1 = new Thread(myPriority);
    		Thread t2 = new Thread(myPriority);
    		Thread t3 = new Thread(myPriority);
    		Thread t4 = new Thread(myPriority);
    		Thread t5 = new Thread(myPriority);
    		Thread t6 = new Thread(myPriority);
    		//设置优先级
    		t1.start();
    		t2.setPriority(1);
    		t3.setPriority(4);
    		t4.setPriority(Thread.MAX_PRIORITY);
    		t5.setPriority(5);
    		t6.setPriority(7);
    		t2.start();
    		t3.start();
    		t4.start();
    		t5.start();
    		t6.start();
    	}
    	
    }
    
    class MyPriority implements Runnable{
    
    	@Override
    	public void run() {
    		System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
    	}
    	
    }
    

    守护线程

    线程分为用户线程(比如main)守护线程(比如gc)

    虚拟机必须确保用户线程执行完毕,不用等待守护线程执行完毕

    当只剩下守护线程时,JVM就会退出,只要存在一个用户线程,JVM就不会退出

    public class TestDaemon {
    	
    	public static void main(String[] args) {
    		God god = new God();
    		You you = new You();
    		Thread thread = new Thread(god);
    		thread.setDaemon(true);
    		thread.start();
    		new Thread(you).start();
    	}
    }
    
    class God implements Runnable{
    	
    	@Override
    	public void run() {
    		while(true) {
    			System.out.println("上帝保佑着你");
    		}
    	}
    }
    
    class You implements Runnable{
    
    	@Override
    	public void run() {
    		for(int i = 0;i<=100;i++) {
    			System.out.println("你开心地活了"+i+"年");
    		}
    		System.out.println("GoodBye,World!");
    	}
    	
    }
    
    展开全文
  • Java多线程 - 为什么使用多线程?

    千次阅读 2018-09-30 04:00:53
    Java多线程一:为什么使用多线程? 我可以总结成一句话:为了效率或者说性能。 我们可以分析一下下面两个场景 第一个场景——拍卖 假设有诸多用户在手机上进行出价,大屏幕显示当前最高价和出价记录,主持人最后...

    第一个场景——拍卖

    假设有诸多用户在手机上进行出价,大屏幕显示当前最高价和出价记录,主持人最后点击结束拍卖,进入下一轮。当主持人点击结束的时候,需要把用户的出价记录保存到数据库里头去,可能是几条出价记录,也可能是上千条的出价记录。此时我们需要产生几十到几千条insert语句,可想而知如果我们等几千条insert语句执行完毕再返回类似“结束成功,可以进入下一轮拍卖”的数据是需要一定的时间的。此时我们就可以开启一个线程去执行insert操作。而我们的主线程则直接返回”成功“的信息。这样就成功的减少了请求返回的时间。这里说的是理想状态,排除插入数据的线程执行过程中失败的因素。如果要处理,可以加入缓存。数据存入缓存后视为成功并作出请求响应,当插入数据线程成功执行后清理缓存。如果失败,则通过定时器或手动执行补偿。

    第二个场景——数据分析

    现在我们需要从A服务器去拿到几千、几万、几十万甚至上亿的数据,假设需要花费5秒钟。然后从B服务器也去拿这么多的数据,假设也需要花费5秒钟。然后两个数据结合起来进行数据分析。如果不采用多线程,我们可能需要先从A服务器获取数据,五秒以后才能从B获取数据,这里总共花费了十秒钟的时间去获取数据。那么如果采用多线程,我们可以创建两个线程,分别去拿A和B的数据,这样只需要花费5秒钟的时间。从而提高了数据处理的速度。

    除了列举的两个场景以外,还有很多场景都可以使用到多线程。在工作中可以慢慢体会!

    (完)

    展开全文
  • Java多线程超详解

    万次阅读 多人点赞 2019-06-11 01:00:30
    随着计算机的配置越来越高,我们需要将进程进一步优化,细分为线程,充分提高图形化界面的多线程的开发。这就要求对线程的掌握很彻底。 那么话不多说,今天本帅将记录自己线程的学习。 线程的相关API //获取当前...
  • Java多线程学习(吐血超详细总结)

    万次阅读 多人点赞 2015-03-14 13:13:17
    本文主要讲了java多线程使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。
  • Java多线程

    万次阅读 2018-08-25 14:12:06
    JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。 1、继承...
  • Java什么用多线程

    千次阅读 2018-09-05 00:16:55
    用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法...
  • 多线程和单线程的联系与区别 答: 1.在单核CPU中,将CPU分为很小的时间片,在每一时刻只能有一个线程在执行,是一种微观上轮流占用CPU的机制。 2.多线程会存在线程上下文切换,会导致程序执行速度变慢,即采用一个...
  • JAVA线程与多线程

    千次阅读 多人点赞 2016-08-25 19:10:10
    多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。● 线程java中的线程使用java.lang.Thread类或者java.lang.Ru
  • Java多线程学习

    千次阅读 多人点赞 2018-04-09 00:45:52
    一、java多线程系列Java多线程学习(一)Java多线程入门Java多线程学习(二)synchronized关键字(1)Java多线程学习(二)synchronized关键字...通信知识点补充Java多线程学习(六)Lock锁的使用二、java多线程思维...
  • Java多线程:到底什么时候该用多线程

    万次阅读 多人点赞 2018-09-30 16:27:29
    系统接受实现多用户多请求的高并发时,通过多线程来实现。   二、线程后台处理大任务 一个程序是线性执行的。如果程序执行到要花大量时间处理的任务时,那主程序就得等待其执行完才能继续执行下面的...
  • 使用多线程时,一定要知道一个道理:处理速度的最终决定因素是CPU、内存等,在单CPU(无论多少核)上,分配CPU资源的单位是“进程”而不是“线程”。 我们可以做一个简单的试验: 假设我要拷贝100万条数据,单...
  • Java多线程之暂停线程

    千次阅读 2019-08-11 01:23:13
    Java多线程中,suspend()方法可以暂停线程,resume()方法可以恢复线程。 这两个方法都是已经过时的方法。 1.8.1suspend与resume方法的使用 package cn.zxyy.multiThread.Thread.suspendThread; public class ...
  • Java单线程与多线程

    千次阅读 2019-03-08 18:17:52
    在我们了解单线程和多线程之前,我们必须搞清楚什么是进程。 一个运行起来的程序就是一个进程! 那程序又是什么呢? 对程序的通俗定义就是:一段可执行的代码。 当我们执行一段Java程序时,就在java虚拟机(JVM)中...
  • java多线程和spring多线程实现

    千次阅读 2018-04-02 16:37:18
    java多线程和spring多线程实现 线程thread 线程的创建方法: 1、继承Thread类创建新的可执行线程 class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = ...
  • Java 多线程:线程优先级

    千次阅读 2017-01-15 14:45:11
    Java 多线程:线程优先级
  • Java并发编程一 多线程

    千次阅读 2018-05-04 16:36:30
    Java并发编程一 多线程Java并发编程是一个很热点的话题,无论在面试时候还是在高并发的场景中。都会涉及到Java的并发编程相关的知识。Java的并发编程有两个主要的基础知识,一个是线程安全另一个是线程间通信。 摘要...
  • Java多线程面试题

    万次阅读 2020-10-25 15:56:40
    wait 方法: 是 Object 的方法,必须与 synchronized 关键字一起使用线程进入阻塞状态,当 notify 或者 notifyall 被调用后,会解除阻塞。但是,只有重新占用互斥锁之后才会进入可运行状态。睡眠时,释放互斥锁。 ...
  • @FunctionalInterface public interface Runnable { public abstract void run(); }
  • java多线程编程实例

    万次阅读 多人点赞 2018-05-25 10:01:22
    1.相关知识:Java多线程程序设计到的知识:(1)对同一个数量进行操作(2)对同一个对象进行操作(3)回调方法使用(4)线程同步,死锁问题(5)线程通信等等2.示例2.1三个售票窗口同时出售20张票程序分析: (1)...
  • 总结-Java何时需要使用多线程

    万次阅读 2016-02-11 20:20:54
    多线程使用的主要目的在于: 1、吞吐量:你做WEB,容器帮你做了多线程,但是他只能帮你做请求层面的。简单的说,可能就是一个请求一个线程。或多个请求一个线程。如果是单线程,那同时只能处理一个用户的请求。 2...
  • Java项目中什么时候需要多线程?比如什么项目中那个模块用到了
  • java使用多线程导出excel

    千次阅读 2019-12-11 18:55:42
    由于单表的数据量特别大,发现在最终导出excel的时候,由于数量太大,导出速度特别慢,想了一些办法,不管使用何种API,单线程始终是操作的瓶颈,因此最终考虑使用多线程进行改善 总体思路: 1、数据总量分段 2、每...
  • Java笔记--多线程

    千次阅读 多人点赞 2018-07-20 14:24:32
    Java笔记–多线程 在讲线程之前有必要讨论一下进程的定义:进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。进程实体由程序段, 数据段 PCB(进程控制块)组成。线程又是什么?...
  • java有返回值的多线程并发

    千次阅读 2019-03-20 10:32:34
    Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的多线程。 其中前两种方式线程执行...
  • 系统接受实现多用户多请求的高并发时,通过多线程来实现。 二、线程后台处理大任务 一个程序是线性执行的。如果程序执行到要花大量时间处理的任务时,那主程序就得等待其执行完才能继续执行下面的。那用户就不得...
  • Java的线程和多线程教程

    千次阅读 2014-05-21 01:16:14
    Java中的Thread类提供了多线程(multi-threading)功能,应用程序可以创建多个线程并同时运行。  在一个应用程序中,通常会有两种类型的线程-用户线程(user thread)和守护线程(daemon thread)。当我们启动引用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,261,419
精华内容 504,567
关键字:

java什么情况用多线程

java 订阅