进程与线程
1.进程:当某个程序在执行是,发送请求就是一个进程,例如一首音乐的播放
2.线程; 一个进程中一个单一顺序的流,一个进程中可以并发多个线程,每条线程执执行不同的任务。
线程就是提前创建若干个线程,如果有任务需要处理,线程池里的线程就会处理任务,处理完之后线程并不会被销毁,而是等待下一个任务。由于创建和销毁线程都是消耗系统资源的,所以当你想要频繁的创建和销毁线程的时候就可以考虑使用线程池来提升系统的性能。
创建线程的三种方法:
1.继承Thread方法
1). 定义线程类
继承Thread方法时,需要重写Thread的run()方法。run()方法中的代码就是你要并发执行的代码。
``
class ExampleThread extends Thread {
@Override
public void run() {
doSomething();
}
}
在main()方法里创建一个ExampleThread对象,调用该对象的start()方法,start()方法会通过对系统底层的一系列操作,创建出一个相应的线程,与当前线程并发执行。如果直接调用run()方法,程序将执行完run()方法后才会执行main()方法中后面的代码,这样就是单线程执行而不是多线程并发执行了。
public class CreateThread {
public static void main(String[] args) {
ExampleThread thread = new ExampleThread();
thread.start();//注意是start(),不是run()
//下面的代码可以和run()方法里的代码并发执行
doSomethingElse();
}
}
*2.实现Runnable接口*
1). 定义线程类
使用Runnable接口与继承Thread类的用法类似,也是在新的类中编写run()方法,方法中的内容就是新建线程要执行的代码。
public class CreateThread {
public static void main(String[] args) {
Runnable runnable = new ExampleThread()
Thread thread = new Thread(runnable);
thread.start();//注意是start(),不是run()
//下面的代码可以和run()方法里的代码并发执行
doSomethingElse();
}
}
*3.实现Callable接口*
1). 定义线程类
前面说的使用Thread和Runnable实现多线程的方法都不能从上一个线程中得到返回值,可是有些时候当一个线程运行结束的时候你想让它返回一些有价值的信息,比如某些操作是否执行成功了。Callable接口就是用于解决这类问题的,Callable接口是一个带泛型的接口,泛型的类型就是线程返回值的类型。实现Callable接口中的call()方法,方法的返回类型与泛型的类型相同
class ExampleThread implements Callable<String> {
@Override
public String call() {
doSomething();
return "Some Value";
}
}
2). 执行线程类的代码
执行这个线程类的方法与Runnable类似,但是Callable在调用start()方法之前需要先包一层FutureTask,FutureTask用于获得线程返回的数值,具体代码如下:
public class CreateThread {
public static void main(String[] args) {
Callable callable = new ExampleThread();
FutureTask task = new FutureTask(callable);
Thread thread = new Thread(task);
thread.start();//注意是start(),不是call()
doSomethingElse();
try {
String returnVal = task.get();//这里就得到了线程的返回值
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
这里有一个需要注意的地方,当调用task.get()的时候,新创建的线程可能还没有执行完,这时调用get()方法当前线程就会被阻塞,直到新创建的线程执行结束。因此,task.get()代码最好是在当前线程不得不用这个返回值时再调用,这样当前线程可以继续执行与返回值无关的代码。
总结
通过继承Thread类和实现Runnable接口生成的线程都是没有返回值的,实现Callable接口的线程可以有返回值,但是要注意不要过早的阻塞当前线程。
继承Thread类和实现Runnable接口二者之间各有好处,继承Thread类可以方便的使用到start()方法启动线程,但同时也带来一个弊端:继承使新类和Thread类产生强耦合,此外,由于Java不支持多继承,新的类也不能再继承其他的类。实现Runnable接口与之相反。
2万+

被折叠的 条评论
为什么被折叠?



