java多线程:创建、join方法

一、进程和线程的区别
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。
线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
新建状态(New):新建的线程处于新建状态,如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2.同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
3.其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
二、实现线程的方式:
JAVA多线程实现方式主要下面几种:继承Thread类、实现Runnable接口、实现Callable接口、使用ExecutorService。
三、线程调度
Java线程优先级高的线程会获得较多的运行机会
Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
static int MAX_PRIORITY:线程可以具有的最高优先级,取值为10。
static int MIN_PRIORITY:线程可以具有的最低优先级,取值为1。
static int NORM_PRIORITY:分配给线程的默认优先级,取值为5。
每个线程都有默认的优先级,缺省优先级为 NORM_PRIORITY。
有关优先级的方法有两个:
final void setPriority(int newp) : 修改线程的当前优先级
final int getPriority() : 返回线程的优先级
主线程的默认优先级为Thread.NORM_PRIORITY。
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。
JVM提供了10个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,
应该仅仅使用Thread类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。


//main方法也是一个线程   是普通优先级
public class Test {
    public static void main(String[] args) throws InterruptedException {
        ThreadTest t1=new ThreadTest();
        t1.setName("线程1");//设置线程的名称

        t1.start();//启动线程  不能直接调用run方法
//      t1.sleep(3000);     
        ThreadTest t2=new ThreadTest();
        t2.setName("线程2");

        t2.start();
//      t2.start();//不能两次调用start方法
//      t2.setPriority(10);//设置线程对象的优先级   参数的范围是0-10 默认为5   数值越大表示执行的时间越长的概率越高
//      t1.setPriority(1);
//      t1.setPriority(Thread.NORM_PRIORITY);//也可以使字段常量  MAX_PRIORITY  MIN_PRIORITY  NORM_PRIORITY

        /*Thread t = Thread.currentThread();//获得当前正在执行的线程对象
        for(int i=0;i<600;i++){
            System.out.println(t.getName()+"  "+i);
        }*/
    }
}
//线程:继承Thread类  重写run方法
class ThreadTest extends Thread{

    @Override
    public void run() {
        for(int i=0;i<5000;i++){
            /*if(i==100){
                try {
                    sleep(2000);//让线程对象休眠    参数是毫秒数
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }*/
            yield();//谦让   暂停当前正在执行的线程对象,并执行其他线程
            System.out.println(this.getName()+"  "+i);//获得线程的名称
        }
    }   
}

四、线程join方法
join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。

//线程对象互相join 也会死锁
public class Test1 {
    public static void main(String[] args) {
        Thread1 t1=new Thread1();
        Thread2 t2=new Thread2();

        t1.t2=t2;//给线程对象的属性赋值
        t1.setName("线程1");

        t2.t1=t1;
        t2.setName("线程2");

        t1.start();
        t2.start();
    }
}
class Thread1 extends Thread{
    Thread2 t2;
    @Override
    public void run() {
        for(int i=0;i<500;i++){
            if(i==400){
                try {
                    t2.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }           
            System.out.println(getName()+"  "+i);
        }
    }
}
class Thread2 extends Thread{
    Thread1 t1;
    @Override
    public void run() {
        for(int i=0;i<500;i++){
            if(i==100){
                try {
                    t1.join();//让出当前线程 让t1线程对象执行完
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println(getName()+"  "+i);
        }
    }
}

参考资料:

Java总结篇系列:Java多线程(一)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值