您的位置:首页 > 编程语言 > Java开发

java多线程——启动,生命周期及线程阻塞

2016-06-02 23:04 531 查看
线程和进程的区别:

(1)进程就是一个正在执行的程序,当一个程序执行时,内部可能会有多个执行流,每个执行流就是一个进程。

(2)进程之间不能共享内存等资源,同一进程内的多个线程可以共享进程的资源。

(3)线程属于进程,不能独立执行。每个进程至少要有一个线程,成为主线程。

一、 java多线程的创建

1. 有两种创建方法:

(1)继承Thread类,重写run()方法,然后在main()方法中,调用start()方法,启动该线程。

(2)实现Runnable接口,实现run()方法,然后在main()方法中,new一个实例出来,然后创建代理角色+真实角色的引用,再调用start()方法,启动该线程。

public class ThreadTest {

public static void main(String[] args) {

//继承Thread类
//      Thread1 t1=new Thread1();
//      Thread2 t2=new Thread2();
//      t1.start();
//      t2.start();

//实现Runnable接口
Thread3 t3=new Thread3();
Thread t33=new Thread(t3);
Thread4 t4=new Thread4();
Thread t44=new Thread(t4);
t33.start();
t44.start();

for(int i=0;i<100;i++){
System.out.println("买吃的"+i);
}
}
}

/*
* 用继承Thread的方法创建多线程
*/
class Thread1 extends Thread {
public void run(){
for(int i=0;i<50;i++){
System.out.println("买窝头"+i);
}
}
}

class Thread2 extends Thread{
public void run(){
for(int i=0;i<50;i++){
System.out.println("买包子"+i);
}
}
}

//======================================================

/*
* 用实现Runnable接口的方法创建多线程
*/
class Thread3 implements Runnable {

@Override
public void run() {
for(int i=0;i<50;i++){
System.out.println("蒸馒头"+i);
}
}
}

class Thread4 implements Runnable{

@Override
public void run() {
for(int i=0;i<50;i++){
System.out.println("蒸包子"+i);
}
}
}


2.两种方法的优缺点:

(1)如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

(2)实现Runnable接口可以可以避免java中的单继承的限制。

(3)实现Runnable接口可以实现同一个资源的多个代码的实现。

//用Thread类实现
class Thread5 extends Thread{
int num=10;
String name=null;
public Thread5(String name){
this.name=name;
}
public void run(){
for(int i=0;i<num;i++){
System.out.println(name+"num= "+num--);
}
try {
sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
运行结果为:
包子num= 10
馒头num= 10
馒头num= 9
馒头num= 8
馒头num= 7
馒头num= 6
包子num= 9
包子num= 8
包子num= 7
包子num= 6
*/

//用Runnable接口测试
class Thread6 implements Runnable{

int num=10;

@Override
public void run() {
for (int i = 0; i < num; i++) {
System.out.println(Thread.currentThread().getName() + "num= " + num--);
}
try {
Thread.sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
运行结果为:
窝头num= 10
面包num= 9
面包num= 8
面包num= 7
面包num= 6
面包num= 5
窝头num= 4
窝头num= 3
*/


public static void main(String[] args) {

/*
* 测试资源共享
*/
//测试继承Thread类的资源共享
Thread5 t51=new Thread5("馒头");
t51.start();
Thread5 t52=new Thread5("包子");
t52.start();
//测试实现Runnable接口的资源共享
Thread6 t6=new Thread6();
Thread t61=new Thread(t6,"窝头");
Thread t62=new Thread(t6, "面包");
t61.start();
t62.start();
}
}


二、多线程的生命周期



1. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。

2. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

3. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

线程阻塞的情况:

1. 等待阻塞:运行的线程执行wait(),jvm把该线程放入线程池中;

2. 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则jvm会把该线程放入锁池中;

3. 其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,jvm会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: