多线程介绍
进程:进程指正在运行的程序,即一段程序执行的过程。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,一个进程中可以有多个线程,则这个应用程序也可以被称之为多线程程序。
多线程的实现
- 1 实现Runnable接口
推荐
//创建的新的线程
public class SubRunnable implements Runnable{
//线程需要完成的任务放到run()方法中
public void run(){
for(int i=0;i<50;i++){
System.out.println("run:"+i);
}
}
}
//调用创建的新线程
public class ThreadDemo{
public static void main(String[] args){
SubRunnable sr = new SubRunnable();
Thread t = new Thread(sr);
t.start();//start() 使线程开始执行,同时让JVM调用该线程的run方法
for(int i=0;i<50;i++){
System.out.println("main:"+i);
}
}
}
//运行结果是既有"run:i"也有"main:i",并且没有固定顺序,证明main线程和SubThread线程都执行
- 2 实现Callable<Object>接口
//创建的新的线程
public class SubCallable implements Callable<String>{
//线程需要完成的任务放到run()方法中
public String call() throws Exception{
return "实现Callable<Object>接口的线程执行";
}
}
//调用创建的新线程
public class ThreadDemo{
public static void main(String[] args){
SubCallable sc = new SubCallable();
Thread t = new Thread(sc);
t.start();//start() 使线程开始执行,同时让JVM调用该线程的run方法
}
}
实现Callable<Object>接口实现的线程,其线程执行方法call()可以有返回值,并且该方法可以抛出异常
- 3 继承Thread类
//创建的新的线程
public class SubThread extends Thread{
public void run(){
for(int i=0;i<50;i++){
System.out.println("run:"+i);
}
}
}
//调用创建的新线程
public class ThreadDemo{
public static void main(String[] args){
SubThread st = new SubThread();
st.start();//start() 使线程开始执行,同时让JVM调用该线程的run方法
for(int i=0;i<50;i++){
System.out.println("main:"+i);
}
}
}
//运行结果是既有"run:i"也有"main:i",并且没有固定顺序,证明main线程和SubThread线程都执行
//多线程的具体执行过程见下图
实现Runnable接口相对于继承Thread类的好处:
继承Runnable接口避免了单继承的局限性;
实现Runnable接口实现了线程接口对象与线程任务的分离,实现了解耦合
- 4 获取线程名
public class NameThread extends Thread{
public void run(){
//1.直接通过父类的getName()方法获得当前线程名
System.out.println(super.getName());
}
}
public class ThreadDemo{
public static void main(String[] args){
NameThread nt = new NameThread();
nt.start();
//2.通过父类的静态方法currentThread()获得当前线程对象,再调用getName()方法
Sytem.out.println(Thread.currentThread().getName());
//3.手动设置线程名再调用
NameThread nt = new NameThread("thread-01");
//nt.setName("thread-01");
nt.start();
Sytem.out.println(nt.getName());
}
}
- 5 线程的休眠
public class ThreadDemo{
public static void main(String[] args){
for(int i=0;i<50;i++){
Thread.sleep(1000);//在指定毫秒数内,让线程休眠/暂停执行
System.out.println("main:"+i);
}
}
}
- 6 匿名内部类实现多线程
public class ThreadDemo{
public static void main(String[] args){
//继承Thread类方式
new Thread(){
public void run(){
System.out.println("继承Thread类的匿名内部类多线程的实现");
}
}.start();
//实现Runnable接口方式
Runnable r = new Runnable(){
public void run(){
System.out.println("实现Runnable接口的匿名内部类多线程的实现");
}
}
new Thread(r).start();
}
}
-
7 线程的不同状态转换
8 线程池的使用
/*实现Runnable接口的线程*/
public class ThreadPoolRunnable implements Runnable{
public void run(){
Sop(Thread.currentThread().getName()+"线程执行")
}
}
/*实现Callable<Object>接口的线程*/
public class ThreadPoolCallable implements Callable<String>{
public String call() throws Exception{
return Thread.currentThread().getName()+"线程执行";
}
}
/*使用线程池*/
public class ThreadPoolDemo{
public static void main(String[] args) throws Exception{
//
//调用工厂类的静态方法,创建线程池对象
//返回的是实现线程池接口的线程池对象
ExecutorService es = Executors.newFixedThreadPool(2);//参数表示该线程池中线程的个数
//调用接口实现类对象es中的方法submit()提交线程任务
es.submit(new ThreadPoolRunnable());
Future<String> f = es.submit(new ThreadPoolCallable());
Sop(f.get());
//销毁子线程池(一般不用)
//es.shutdown();
}
}