Java 多线程 快速入门
首先多说一句,其实多线程是和相应的编程范式以及软件设计相契合的,如果只是单纯的谈多线程,其实学习效果不会太好 ...
同时网络上关于这一主题的内容早已是车载斗量,所以这一系列文章完全是我自己的胡乱涂了 ..
1:什么是线程?
线程就是程序中单独顺序的控制流,线程本身不能运行,它只能纯在与进程之中 ;
进程就是指正在运行的程序,进程是一个动态的概念 ;
所谓多线程,就是指在单个进程中同时运行多个不同的线程执行不同的任务 ;
线程的本质就是对程序执行的控制 ;
2:多线程的目的
从软件设计的角度上来讲,存在着很多的目的,多线程范式本身就是一种重要的设计思想,比如“事件驱动模型”,
这里主要从计算机硬件运算的角度看多线程,那就是“最大限度的利用CPU”,当某一线程的处理不需要占用CPU
而只和I/O等资源打交道时,让需要占用CPU资源的其他线程有机会获得CPU资源。
3:Java中的多线程
这是本文主要的内容,会详细分析 ;
Java程序只要被执行,就会自动产生一个Main线程(一般称为“主线程”),Java中的Main方法就是在Main线程上执行的,
有一点需要明确,程序都是由线程来执行 ;
需要注意的几点:
· 多线程共享一块内存空间和一组系统资源,有可能相互影响 ;
· 线程共享相同的地址空间并且共享同一个进程 ;
· 线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,线程的切换代价较小 ;
4:Java 创建线程
· 继承 Thread类,重写run( )方法 ;
· 实现 Runnable接口,现实run( )方法 ;
要注意的是线程的启动需要通过调用start( )方法来实现,该方法不要重写,直接调用父类的就好了,同时线程的启动,也就是
说start( )方法只能被调用一次,重复启动(调用start( ))是会报错的 ;
public class ThreadTest {
public static void main(String[] args) {
Thread1 thread1 = new Thread1("first thread") ;
Thread2 thread2 = new Thread2("second thread") ;
System.out.println(thread1.getName()) ;
System.out.println(thread2.getName()) ;
thread1.start() ;
thread2.start() ;
}
}
class Thread1 extends Thread {
public Thread1(String name) {
super(name) ;
}
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("hello world : " + i);
}
}
}
class Thread2 extends Thread {
public Thread2(String name) {
super(name) ;
}
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("welcome : " + i) ;
}
}
}
Runnable 接口的方式
使用匿名类的方式
public class ThreadTest2 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("内部类 : " + i);
}
}
}) ;
thread.start();
}
}
以实现接口的方式,启动线程的方式是将实现了Runnable( )接口的实例,作为参赛传递给Thread类的构造方法 ;
public class ThreadTest2 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() ) ;
Thread thread2 = new Thread(new MyThread2()) ;
thread.start() ;
thread2.start() ;
}
}
class MyThread implements Runnable {
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("hello : " + i);
}
}
}
class MyThread2 implements Runnable {
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("world : " + i);
}
}
}
这里看下Thread( )类的源代码,思考下为什么要重写或者实现run( )方法 ;
public void run() {
if (target != null) {
target.run();
}
}
继承Thread类时,可以发现run( )方法什么也不做(因为target = null),
而当实现Runnable接口时,调用的正是其自身实现的run方法 ;
5:Java 线程的停止
毫无疑问,很多的文章都提到使用Java自带的线程停止方法stop( )是不可取的,
这需要一个while的死循环,以及一个关闭该死循环的方法 ;
这里给出一个在生产环境中应用过的例子
class MyThread extends Thread {
//线程运行的开关
private volatile boolean shutdownThread = false ;
@Override
public void run() {
try {
while(true) { //设置一个死循环
/**
* do something .....
*
*/
if(shutdownThread && 要做的事情做完了 == 0) {
break ;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 关闭线程
*/
public void shotdownThread() {
shutdownThread = true ;
try {
this.join(); //保证当有多个线程被关闭时能够顺序进行 ;
} catch (InterruptedException e) {
}
}
/**
* 启动线程
*/
public void bootThread() {
this.start() ;
}
}
未完待续 ...