Java提供了Thread类来创建线程,具体看代码
新建下载线程类
package com.iteye.badpie.javacode.thread; import java.util.Random; public class DownloadThread extends Thread { private static final String TAG = DownloadThread.class.getSimpleName(); private String mMovie; private Random mRandom; public DownloadThread(Random random, String movie) { mRandom = random; mMovie = movie; } @Override public void run() { log(TAG, "电影 " + mMovie + " 开始下载"); for (int i = 0; i < 100;) { // 模拟网络下载,随机耗时 synchronized (this) { try { int time = mRandom.nextInt(5000); wait(time); i += 20; } catch (InterruptedException e) { e.printStackTrace(); } } log(TAG, "电影 " + mMovie + " 下载进度... " + i + "%"); } log(TAG, "电影 " + mMovie + " 下载结束"); } private void log(String TAG, Object message) { System.out.println(String.format("%s : %s", TAG, message)); } }
这样启动线程
package com.iteye.badpie.javacode.thread; import java.util.Random; public class Main { public static void main(String[] args) { System.out.println("主线程开始运行"); Random random = new Random(System.currentTimeMillis()); DownloadThread download1 = new DownloadThread(random, "黎明破晓"); download1.start(); DownloadThread download2 = new DownloadThread(random, "人再囧途之泰囧"); download2.start(); System.out.println("主线程运行结束"); } }
某一次执行结果如下:
主线程开始运行 主线程运行结束 DownloadThread : 电影 人再囧途之泰囧 开始下载 DownloadThread : 电影 黎明破晓 开始下载 DownloadThread : 电影 黎明破晓 下载进度... 20% DownloadThread : 电影 人再囧途之泰囧 下载进度... 20% DownloadThread : 电影 黎明破晓 下载进度... 40% DownloadThread : 电影 黎明破晓 下载进度... 60% DownloadThread : 电影 人再囧途之泰囧 下载进度... 40% DownloadThread : 电影 黎明破晓 下载进度... 80% DownloadThread : 电影 黎明破晓 下载进度... 100% DownloadThread : 电影 黎明破晓 下载结束 DownloadThread : 电影 人再囧途之泰囧 下载进度... 60% DownloadThread : 电影 人再囧途之泰囧 下载进度... 80% DownloadThread : 电影 人再囧途之泰囧 下载进度... 100% DownloadThread : 电影 人再囧途之泰囧 下载结束
又一次执行结果如下:
主线程开始运行 主线程运行结束 DownloadThread : 电影 黎明破晓 开始下载 DownloadThread : 电影 人再囧途之泰囧 开始下载 DownloadThread : 电影 黎明破晓 下载进度... 20% DownloadThread : 电影 人再囧途之泰囧 下载进度... 20% DownloadThread : 电影 黎明破晓 下载进度... 40% DownloadThread : 电影 人再囧途之泰囧 下载进度... 40% DownloadThread : 电影 人再囧途之泰囧 下载进度... 60% DownloadThread : 电影 人再囧途之泰囧 下载进度... 80% DownloadThread : 电影 黎明破晓 下载进度... 60% DownloadThread : 电影 人再囧途之泰囧 下载进度... 100% DownloadThread : 电影 人再囧途之泰囧 下载结束 DownloadThread : 电影 黎明破晓 下载进度... 80% DownloadThread : 电影 黎明破晓 下载进度... 100% DownloadThread : 电影 黎明破晓 下载结束
感觉到线程的魅力了么?
这里创建的两个下载线程,下载《黎明破晓》的download1,下载《人再囧途之泰囧》的download2。这里不能确定这两个电影哪个先开始下载,哪个先下载结束。并且,明明main方法运行结束了,也就是主线程运行结束了,而这两个下载任务(两个子线程)还在运行。所以说线程的运行是独立的,并且互不干扰。
一个线程的运行周期就是其run方法(Thread类的run方法),run方法执行结束,该线程也就执行结束了。启动一个线程就调用其start方法(Thread类的start方法)。
来看更多的线程的例子
package com.iteye.badpie.javacode.thread; public class Main { public static void main(String[] args) { System.out.println("主线程开始运行"); new Thread() { @Override public void run() { System.out.println("使用匿名内部类构建子线程"); } }.start(); System.out.println("主线程运行结束"); } }
Thread原生支持Runnable方式的调用
package com.iteye.badpie.javacode.thread; public class Main { public static void main(String[] args) { System.out.println("主线程开始运行"); Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Runnable接口"); } }; // 使用Runnable构建线程,最终线程的执行会调用到Runnable接口的run方法。 new Thread(runnable).start(); System.out.println("主线程运行结束"); } }
执行结果如下:
主线程开始运行 主线程运行结束 Runnable接口
也可以扩展自定义接口
package com.iteye.badpie.javacode.thread; public class DownloadThread extends Thread { private IDownloadTask mTask; public DownloadThread(IDownloadTask task) { mTask = task; } @Override public void run() { System.out.println("执行下载任务"); mTask.download(); } public interface IDownloadTask { public void download(); } }
如此启动
package com.iteye.badpie.javacode.thread; import com.iteye.badpie.javacode.thread.DownloadThread.IDownloadTask; public class Main { public static void main(String[] args) { System.out.println("主线程开始运行"); IDownloadTask task = new IDownloadTask() { @Override public void download() { System.out.println("自定义下载任务开始执行"); System.out.println("自定义下载任务执行结束"); } }; // 使用IDownloadTask构建DownloadThread,最终线程的执行会调用到IDownloadTask接口的download方法。 new DownloadThread(task).start(); System.out.println("主线程运行结束"); } }
执行结果如下:
主线程开始运行 主线程运行结束 执行下载任务 自定义下载任务开始执行 自定义下载任务执行结束