多线程(线程的状态)
CPU的执行资格:可以被cpu处理,在处理队列中排队。
CPU的执行权:正在被cpu处理。
线程的四种状态
被创建
运行:具备着执行资格,具备着执行权
临时阻塞状态:具备着执行资格,但是不具备执行权,正在等待执行权
冻结:释放执行权,同时释放执行资格。
消亡
运行状态到冻结状态的两种转换方式:
运行:sleep(time) :冻结
冻结:sleep(time)时间到 :运行
运行:wait(t) :冻结
冻结:notify()唤醒 :运行
sleep方法需要指定睡眠时间,单位是毫秒。
一个特殊的状态:就绪:具备了执行资格,但是还没有获取资源。
多线程(创建线程的第二种方式—实现Runnable接口)
创建线程的第二种方式:实现Runable接口。
1,定义类实现Runnable接口
2,覆盖接口中的run方法,将线程的任务代码封装到run方法中。
3,通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。
为什么第3步要这么做?
因为线程的任务都封装在Runnable接口子类对象的run方法中。
所以要在线程对象创建时就必须明确要运行的任务。
4,调用线程对象的start方法开启线程。
class Demo implements Runnable{
public void run() {
show();
}
public void show(){
for(int x=0;x<20;x++){
System.out.println(Thread.currentThread().getName()+"...."+x);
}
}
}
public class Thread09_1 {
public static void main(String[] args) {
Demo d=new Demo();
Thread t1=new Thread(d);
Thread t2=new Thread(d);
t1.start();
t2.start();
/*
Demo d=new Demo();
d.start();在这里不可以。因为不是继承。而是实现。
实现有可能会继承了其他父类。同时父类会有run()方法。
* */
}
}
多线程(第二种方式的细节)
interface Runbale {
public void run();
}
/*
多线程的实现代码。
* */
class Thread {
private Runbale r;
Thread(){
}
Thread(Runbale r){
if(r!=null){
this.r=r;}
}
public void run(){
r.run();
}
public void start(){
run();
}
}
//第一种方式
class subThread extends Thread{
public void run(){
System.out.println("haha");
}
}
//第二种方式
class ThreadImpl implements Runbale{
public void run() {
System.out.println("runable run");
}
}
public class Thread10_1 {
public static void main(String[] args) {
// subThread s=new subThread();
// s.start();
ThreadImpl i=new ThreadImpl();
Thread t=new Thread(i);
t.start();
}
}
第二种创建线程的好处
Runnable
它的出现仅仅是将线程的任务进行了对象的封装
Runnable r=new Student();
Thread t=new Thread(r);//传递r,明确线程的任务
t.start();
实现Runnable接口的好处:
1.将线程的任务从线程的子类中分离出来,进行了单独的封装。
按照面向对象的思想将任务的封装成对象。
2.避免了Java单继承的局限性。
所以,创建线程的第二种方式比较常用。