面试相关:java多线程与juc介绍

juc介绍

Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。

下面介绍一下JUCExecutorService的用法:

1、new Thread的弊端:

new Thread(new Runnable() {
		 @Override
		 public void run() {
			// TODO Auto-generated method stub
		 }
	}).start();

(1)线程的创建和释放,需要占用不小的内存和资源,每次new Thread新建对象性能差。

(2)线程缺乏统一管理,相互之间存在资源竞争,可能会占用过多资源而导致死机或者OOM

(3)功能单一,缺乏定时执行,定期执行,线程中断等。

2、ExecutorService的优点:

(1)重用存在的线程,减少对象创建、消亡的开销,性能较好。

(2)可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

(3)提供定时执行,定期执行,单线程,并发数控制等功能。

3、ExecutorService线程池

ExecutorService是Java提供的线程池,也就是,每次需要使用线程时,可以通过Executor获取线程。它可以有效控制最大并发线程数,提高系统资源使用率,同时避免过多资源竞争阻塞,同时提供定时执行、定期执行、单线程、并发数控制等功能,也不用使用TimeTask了。

Java通过Executors提供四种线程池:

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。

newSingleThreadExecutor创建一个单线程化线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。

3.1可缓存线程池

package com.disruptor.demo.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 可缓存线程池
 * @author 零落尘土
 *
 */
public class ExectorServiceTest {
	public static void main(String[] args) {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
		     int index = i;
		    try {
		        Thread.sleep(index * 1000);
		    } catch (InterruptedException e) {
		        e.printStackTrace();
		    }
		    cachedThreadPool.execute(new Runnable() {
		        @Override
		        public void run() {
		            System.out.println(Thread.currentThread().getName()+"  "+index);
		        }
		    });
		}
	    cachedThreadPool .shutdown();
	}
	

}

运行结果如下:

面试相关:java多线程与juc介绍_第1张图片

3.2定长线程池

设置线程池为5

package com.disruptor.demo.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 固定线程池
 * @author 零落尘土
 *
 */
public class ExectorServiceFixPoolTest {
	public static void main(String[] args) {
		ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
		for (int i = 0; i < 10; i++) {
			final Integer index = i;
		    fixedThreadPool.execute(new Runnable() {
		        @Override
		        public void run() {
		            try {
		                System.out.println(Thread.currentThread().getName()+"->"+index.hashCode());
		                Thread.sleep(2000);
		            } catch (InterruptedException e) {
		                // TODO Auto-generated catch block
		                e.printStackTrace();
		            }
		        }
		    });
		}
		fixedThreadPool.shutdown();
	}

}

运行结果:

面试相关:java多线程与juc介绍_第2张图片

3.3定长线程池,支持定时及周期性任务

package com.disruptor.demo.test;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
 * 定长线程池,支持定时及周期性任务
 * @author 零落尘土
 * @since 2019-10-30
 */
public class ExectorServiceScheduledTest {
	public static void main(String[] args) {
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
		scheduledThreadPool.schedule(new Runnable() {
		    public void run() {
		        System.out.println(Thread.currentThread().getName()+":delay 3 seconds");
		    }
		},3, TimeUnit.SECONDS);
		scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
			 @Override
				public void run() {
					System.out.println(Thread.currentThread().getName()+":delay 1 seconds, and excute every 3 seconds");
				}
			}, 1, 3, TimeUnit.SECONDS);
	}

}

执行结果:

面试相关:java多线程与juc介绍_第3张图片

3.4单线程池

package com.disruptor.demo.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 单线程池 
 * @author 零落尘土
 * @since 2019-10-30
 */
public class ExectorServiceSingleTest {
	public static void main(String[] args) {
		ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
		for (int i = 0; i < 10; i++) {
		    final int index = i;
		    singleThreadExecutor.execute(new Runnable() {
		        @Override
		        public void run() {
		            try {
		                System.out.println(Thread.currentThread().getName()+":"+index);
		                Thread.sleep(2000);
		            } catch (InterruptedException e) {
		                // TODO Auto-generated catch block
		                e.printStackTrace();
		            }
		        }
		    });
		}
	}
}

执行结果:

面试相关:java多线程与juc介绍_第4张图片

现在大多数GUI程序都是单线程。适用于批量删除,批量安装等不适合并发但是可能IO阻塞的操作。

你可能感兴趣的:(面试相关)