多线程的目的是最大限度的利用CPU资源
1、进程&线程
1)进程由一个或多个线程组成
2)进程是程序的执行过程(程序就是一段静态的代码段)
3)线程是比进程更小的执行单位,是进程中的“小进程”
4)线程是程序内顺序控制流
5)进程中的线程共享系统分派给进程的内存空间,还有属于自己的内存空间(线程栈)
6)每个线程都有自己的堆栈和程序计数器。你可以把程序计数器设想为用于跟踪线程正在执行的指令。堆栈用于跟踪线程的上下文,上下文是当线程执行到某处时,当前的局部变量的值。
Java中如果我们自己没有定义线程,那么系统就会给我们产生一个线程(主线程,main方法就在主线程上运行),我们的程序都是由线程来执行的。
2、线程的四种可能的状态
1)新建(初始状态)
调用new方法之后,调用start方法之前。在初始状态,可以调用start或stop
2)运行(Runnable)
线程调用了start方法,就转到Runnable状态。线程创建后仅仅占用了内存的资源,在JVM管理的线程中还没有这个线程,此线程必须调用start()方法通知JVM。JVM就知道又有一个新线程排队等候切换了。(所以注意:当线程处于Runnable状态,它也有可能不在运行,因为还有优先级和调度的问题。)
3)中断
四种中断的原因
-JVM将CPU资源从当前线程切换给其他线程,使线程让出了CPU的使用权并处于中断状态
线程的让步是通过Thread.yield()来实现的。yield()方法的作用是:暂停当前正在执行的线程对象,并执行其他线程。
-线程使用CPU资源期间,执行了sleep方法,使当前线程进入休眠状态
Thread.sleep(long millis)和Thread.sleep(long millis, int nanos)静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。当线程睡眠时,它入睡在某个地方,在苏醒之前不会返回到可运行状态。当睡眠时间到期,则返回到可运行状态。
Thread.sleep(123);
-线程使用CPU资源期间,执行了wait方法,使当前线程进入等待状态
-线程使用CPU资源期间,执行某个操作进入阻塞状态,例如I/O请求
4)死亡
线程死亡的原因:
-执行完run()方法中的全部语句,结束run()方法
-线程被强制终止,即强制run()方法结束
5、创建线程的方法
1)继承Thread类,重写run方法
Thread类下的五个方法:
run():该方法用于线程的执行。你需要重写该方法,以便让线程做特定的工作
start():使线程启动run()方法
stop():与start相反,停止线程的运行
suspend():该方法同stop()方法不同的时,它并没有终止未完成的线程,它仅仅是挂起线程,以后还可以恢复。
resume():该方法重新启动已经挂起的线程
public class ThreadTest
{
public static void main(String[] args)
{
Thread1 th1=new Thread1("first thread");
Thread2 th2=new Thread2("secong thread");
System.out.println(th1.getName());
System.out.println(th2.getName());
th1.start();
th2.start();
}
}
class Thread1 extends Thread
{
public Thread1(String name)
{
super(name);
}
@Override
public void run()
{
for(int i=0;i<10;i++)
{
System.out.println("Hello World"+i);
}
}
}
class Thread2 extends Thread
{
public Thread2(String name){
super(name);
}
@Override
public void run()
{
for(int i=0;i<10;i++)
{
System.out.println("Welcome"+i);
}
}
}
继承Thread类,我们要重写run方法,因为run方法中此时什么事都没有做。
修改线程名的两种方式:
1)构造方法
2)setName()方法
注意:1)在调用start()方法前后都可以使用setName设置线程名
2)但在调用start()方法后使用setName修改线程名,会产生不确定性
Thread类的start方法不能多次调用,如调用thread.start()方法,会抛出IllegalThreadStateException异常
2)通过定义实现Runnable接口的类进而实现run方法
public class MyThread2 implements Runnable
{
@Override
public void run()
{
// TODO Auto-generated method stub
for(int i=0;i<10;i++)
System.out.println("hello world"+i);
}
}
Thread类也实现了Runnable接口,因此也实现了Runnable接口中的run方法。
6、线程优先级
可以通过设置线程的属性和方法来该改变线程的优先级
1)设置线程的优先级(setPriority)
2) 设置线程名(setName)
3)设置线程类型 (setDaemon)
参考资料:http://www.cnblogs.com/riskyer/p/3263032.html