java并发学习--第一章 线程的创建
所谓的并发就是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。所以我们看似几个线程在同时进行,其实在操作系统中实际只会运行一个线程,并发过程就是快速切换线程的执行过程。
一、java中自带的线程创建方式
1.通过基础Thread
类,实现其run方法,完成线程创建
public class OneThread extends Thread { //run方法就是线程要执行的方法 public void run(){ System.out.println("这是一个线程"); } public static void main(String[] args) { OneThread oneThread=new OneThread(); //通过线程的实例调用start方法,执行线程run方法 oneThread.start(); } }
2.通过声明Runnable 接口,实现run方法,创建线程
public class ThreadDemo implements Runnable { @Override public void run() { System.out.println("这是Runnable接口实现的线程"); } public static void main(String[] args) { //先创建线程的实例 ThreadDemo threadDemo = new ThreadDemo(); //将线程放入thread方法中 Thread thread = new Thread(threadDemo); //启动线程 thread.start(); } }
3.带返回值的线程,实现Callable<返回值类型>
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class ThreadDemo implements Callable<String> { public static void main(String[] args) throws ExecutionException, InterruptedException { ThreadDemo threadDemo = new ThreadDemo(); //将线程任务放入FutureTask中 FutureTask<String> task = new FutureTask<>(threadDemo); //将task放入Thread类中 Thread thread = new Thread(task); //开始线程任务 thread.start(); //获得执行的结构 String str = task.get(); System.out.println(str); } /** * 线程任务的方法,声明Callable接口重写的线程任务方法 * * @return * @throws Exception */ @Override public String call() throws Exception { return "这是一个带返回值的线程"; } }
二、线程池的创建
java中为我们提供了四种创建线程池的方式:
1.newCachedThreadPool:一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
public class ThreadDemo extends Thread { //用static修饰表示该线程池只创建一次 static ExecutorService CachedExecutor = Executors.newCachedThreadPool(); public static void main(String[] args) { //创建线程实例 ThreadDemo threadDemo = new ThreadDemo(); //将线程丢进线程池中 CachedExecutor.execute(threadDemo); } @Override public void run() { System.out.println("这是一个线程"); } }
2.newFixedThreadPool:一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
public class ThreadDemo extends Thread { //用static修饰表示该线程池只创建一次 static ExecutorService fixedExecutor = Executors.newFixedThreadPool(5); public static void main(String[] args) { //创建线程实例 ThreadDemo threadDemo = new ThreadDemo(); //将线程丢进线程池中 fixedExecutor.execute(threadDemo); } @Override public void run() { System.out.println("这是一个线程"); } }
3.newScheduledThreadPool:这是一个定时器的任务线程池,其中第三个参数TimeUnit类,可以参考https://www.cnblogs.com/zhaoyanjun/p/5486726.html
public class ThreadDemo extends Thread { //用static修饰表示该线程池只创建一次 static ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(5); public static void main(String[] args) { //创建线程实例 ThreadDemo threadDemo = new ThreadDemo(); //定时器任务的线程,三个参数意义是:1.线程任务 2.时间的次数 3.时间的粒度 //该方法的意义是每5分钟一次执行线程threadDemo scheduledExecutor.schedule(threadDemo, 5, TimeUnit.MINUTES); } @Override public void run() { System.out.println("这是一个线程"); } }
4.newSingleThreadExecutor:按顺序来执行线程任务 但是不同于单线程,这个线程池只是只能存在一个线程,这个线程死后另外一个线程会补上。
public class ThreadDemo extends Thread { //用static修饰表示该线程池只创建一次 static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); public static void main(String[] args) { //创建线程实例 ThreadDemo threadDemo = new ThreadDemo(); //将线程放入线程池 singleThreadExecutor.execute(threadDemo); } @Override public void run() { System.out.println("这是一个线程"); } }