线程是运行中的程序的调度单位,多线程问题可以理解为多任务的并行处理问题,因此更多牵涉同步和异步问题;
进程与线程的区别
进程拥有自己的一整套变量,线程需要共享变量。
线程的实现方法
第一种实现方法
(1)创建一个Runnable对象;
(2)用Runnable对象创建一个线程;
(3)启动线程;
Runnable runnable = new Runnable({
@Override
public void run() {
System.out.println("finish---in ---runnable");
}
});
Thread thread = new Thread(runnable);
thread.start();
第二种实现方法
(1)新建一个继承于Thread的类MyThread
(2)新建一个MyThread对象;
(3)启动线程;
MyThread.java
public class MyThread extends Thread{
String tag;
public MyThread(String tag) {
this.tag = tag;
}
@Override
public void run() {
System.out.println("finish---in ---" + tag);
}
}
MyThread myThread = new MyThread("MyThread");
myThread.start();
第三种实现方法
(1)新建一个实现了Runnable的接口MyRunnable;
(2)用新建的Runable对象新建一个MyThread对象;
(3)启动线程;
MyRunnable.java
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("finish---in ---MyRunnable");
}
}
Thread thread = new Thread(new MyRunnable(){});
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.start();
第四种实现方法
(1)使用Callable接口和FutureTask创建线程;创建实现Callable接口的类,并实现call();
(2)使用FutureTask类包装callable实现类的对象,最后将FutureTask对象作为Thread对象的
target;
(3)启动线程;
FutureTask<Integer> ft =
new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 10;
}
});
Thread thread = new Thread(ft);
thread.start();
try {
Integer value = ft.get(1000, TimeUnit.MILLISECONDS);
System.out.println(value.toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
FutureTask
一个FutureTask可以用来包装一个Callable或Runnable对象. 因为FutureTask实现了Runnable接口, a一个FutureTask能够被提交到Executor去执行。
第五种方法
(1)使用Runnable和FutureTask创建线程;
(2)将FutureTask对象作为Thread对象的target;
(3)启动线程;
FutureTask<Integer> ft =
new FutureTask<Integer>(new MyRunnable(),100);//第二个参数是返回值和<?>对应类型
Thread thread = new Thread(ft);
thread.start();
try {
Integer value = ft.get(1000, TimeUnit.MILLISECONDS);
System.out.println(value.toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
区分Runnable,Callable,Future
Runnable
无返回值的异步任务
Callable
有返回值的异步任务,这是一个功能性接口,因此一个lambda表达式或方法参考可以作为赋值的目标。
一个task,可能返回一个结果,也可能会抛出一个异常;实现该接口的类定义一个不带参数的方法call,Callable接口类似于Runnable,都是设计给可能被另一个线程执行的类的实例。Runnable没有返回值,也不会抛出一个已检查异常。
Future
用来代表异步计算的结果。提供方法以检查计算是否完成,等待其完成,并检索计算结果。只有当计算完成时,才能得到结果,如果必要的话,就让它处于阻塞态,直到它到达就绪态。取消通过取消方法执行。提供其他方法以确定任务是否正常完成或被取消。一旦计算完成,计算不能被取消。如果你想用Future为了可取消性但是为了提供一个可用的结果, 你可以声明Future