Thread
学习线程之前先要了解线程与进程的区别。
我们的计算机中的一个程序就是一个进程,一个程序中有很多个线程去完成各种各样的任务。
用一个生活的例子来说,一条商业街,街上两旁有一家一家不同的商店,有卖衣服的,饮食的等等。这些商店可以比作一个个进程。而没一个商店里会有店里的员工,这些员工有负责收银的,有招待客户的等等,就好比进程中的线程一样。
在没有学习线程之前,我们的程序都是单一线程的。在main方法开始,把main代码执行完毕然后程序结束。所以的业务都是靠主线程main这条线程去完成。就好比一家商店一个老板,员工也是他,所有事情也是老板一个人干完,这样效率非常低哦。如果说多几个员工一起干活,分工合作,这样效率才会高哦。
值得注意的是,商店与商店之间的资源是很难共享的哦,比方说天气热了,我A商店想用一下D商店空调,这明显是很难的。但是A商店里的员工1想和员工2共用一个空调,那是轻而易举的事情。所以说进程与进程之间很难资源共享,线程与线程之间可以资源共享。
-----------------------------------------
Thread线程类
构造器中可以传入一个String参数,作为线程名称,不传则使用默认的线程名称。
常用方法:
start( ) 线程开始执行,java虚拟机开始执行run方法
run( ) 线程执行的任务代码
sleep( long millis) 让线程休眠,参数为毫秒long类型。
-----------------------------------------
首先看看java的主线程名称叫什么,这里用到一个Thread的静态方法currentThread(),得到当前线程对象,从而获得线程名。
public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); }原来java的主线程名就叫做 main
-----------------------------------------
创建线程方法1,新建一个类继承Thread类,重写run方法,然后new出对象,start()开启线程。
public class Thread01 extends Thread{ public void run(){ System.out.println("run "+getName()); } }
public class Main { public static void main(String[] args){ Thread thread=new Thread01(); thread.start(); } }
也可以用无名内部类的写法哦,这样代码简洁。
public class Main { public static void main(String[] args) { new Thread() { public void run() { System.out.println(getName()); } }.start(); } }
创建线程方法2,新建一个类实现Runnable接口,实现run方法,然后new出Runnable对象,传入Thread构造器中,开启线程。
这种实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。
public class Thread01 implements Runnable{ public void run(){ System.out.println("run "+Thread.currentThread().getName()); } }
public class Main { public static void main(String[] args) { new Thread(new Thread01()).start(); } }
也可以用无名内部类的写法哦,这样代码简洁。
public class Main { public static void main(String[] args) { new Thread(()->{ System.out.println(Thread.currentThread().getName()); }).start(); } }
-----------------------------------------
线程池
线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
Executors类的newFixedThreadPool(int)方法,获得线程池对象,传入int参数是设置线程池中线程的个数。返回是ExecutorService线程池对象。
submit()方法提交任务方法。
submit方法的参数可以提交Runnable类型任务,或者Callable类型任务。返回是Future对象,可以通过Future对象的get方法获得执行Callable任务的返回值。
那么Callable是什么呢?
Callable接口与Runnable接口功能相似,也是用来指定线程任务的。但与Runnable不同的是Callable有返回值,和有异常抛出。
其中的call( ) 方法,就相当与run( ) 方法。
用法:
public class Thread01 implements Callable<String> { @Override public String call() throws Exception { return Thread.currentThread().getName(); } }
public class Main { public static void main(String[] args){ ExecutorService executorService=Executors.newFixedThreadPool(2); Future<String> future=executorService.submit(new Thread01()); try { System.out.println(future.get()); }catch (Exception ex){ System.out.println(ex); } } }