黑马程序员-----java线程学习与总结

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

1、线程的概念
Thread,是一个进程更加微观的一个对象。进程是OS任务调度的最基本单位。
独立性:线程不能独立存在,线程依赖于进程存在。
存储区域:进程中的数据存在堆栈中,线程的数据存在于寄存器中。
粒度:线程小,进程大。


2、Java中关于线程的API
线程的API包括一个java.lang.Thread类和一个接口java.lang.Runnable接口。

Runnable接口只有一个抽象run()方法。而Thread类实际上是对Runnable接口的实现。

Thread的方法大概分为3类:
获取线程信息方法:getName()/getPriority()
设置线程信息方法:
setName()/setPriority()
有关线程生命周期的方法
Sleep()/join()/interrupt()/interrupted()/isAlive()/run()/resume()/suspend()/start()

 

3、实现线程的方式
Thread():构造一个缺省线程类
Thread(String name):构造一个名称为name的线程类
Thread(Runnable r):构造由R实现的线程类
Thread(Runnable r,String name):构造由R实现,名称为name的线程。

我们定义线程类,核心机制重写run()方法,在run()方法中写线程的功能代码。

(1)自定义的类继承Thread类实现
第一步:定义run()方法

第二步:创建线程对象并启动线程,通过start()方法来间接调用run()方法,不能直接调用run()方法。

(2)自定义的类实现Runnable接口实现
第一步:定义run()方法
第二步:创建线程对象并启动线程。

如下:

package com.tai.GX;

public class ThreadText
{
    public static void main(String[] args)
    {
        //第一种实现方式  创建匿名Thread的子类,复写Thread的run方法 运行的时候就会自动调用run方法
        new Thread(){
            public void run() {
                while (true)
                {
                    try
                    {
                        Thread.sleep(1500);
                        System.out.println(this.getName());//这里的this 就是当前正在运行的线程  相当于 Thread.currentThread
                        system.out.println("this Thread can do something footloose!");
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }                    
                }
            };
        }.start();
        //第二种实现方式 创建Thread是传入一个Runnable接口的子类并复写其Run方法
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                while (true)
                {
                    try
                    {
                        Thread.sleep(1500);
                        System.out.println(Thread.currentThread().getName());
                        system.out.println("this Thread can do something footloose!");
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }    
                }
            }
        }).start();
        
        //因为Thread也实现了Runnable接口这里也可以这样用,我就是试试  其实不合理的
        new Thread(new Thread(){
            @Override
            public void run()
            {
                while (true)
                {
                    try
                    {
                        Thread.sleep(1500);
                        System.out.println(this.getName());
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        
        //这里的既复写Thread的run方法 又传入了Runnable子类 这时候会发生什么情况呢 ?
        
        //这时候就需要看源码了:Thread类中有个Runnable对象,也就是构造方法传入的对象   Thread类的run方法会先判断时候有传入Runnable对象
        //有的话就执行Runnable类的run方法  但是,这里复写了Thread的run方法,所以执行的时候就会执行子类复写过的run方法,所以这里就打印出
        //From Runnable subClass!
        //From this thread!
        
        //super.run就是先调用负类的方法  如果去掉就不会打印出Runnable子类方法中的输出语句
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println("From Runnable subClass!");
            }
        }){
            public void run() {
                super.run();
                System.out.println("From this thread!");
            };
        }.start();
        
    }
}

4、线程的生命周期
创建:使用new运算符实例化一个线程对象,那么该线程对象就创建了。通过调用start()方法,可以启动该线程并且进入了就绪阶段。
就绪:就绪阶段可以分为两种情况:可运行状态(Runnable),正在运行状态(Running)。在任意一个时间片,只能有一个线程控制CPU。控制CPU的线程称为正在运行的线程,其他的线程称为可运行状态。
阻塞:处于阻塞状态的线程就失去了争抢CPU控制权的资格。阻塞状态又分为4种情况:休眠、等待、中断、挂起。
就绪休眠:sleep(n),经过n ms后该线程自动返回到就绪状态。
就绪挂起:suspend(),反过来使用resume()恢复该线程到就绪状态。这两对方法不推荐使用。
就绪中断:interrupt()方法,反过来,使用interrupted()方法。
就绪等待:wait()方法,反过来,使用notify()/notifyAll().
死亡:一个线程一旦运行完毕,即进行死亡状态,释放自身占用的资源。从死亡状态无法再返回到其他状态。

public class SuspendThread extends Thread {
    //定义构造方法
    public SuspendThread(String name)
    {
        super(name);
    }
    //线程 体
    public void run()
    {
        System.out.println("线程体开始执行");
        for(int i=0;i<1000000;i++)
        {
            double d = 10;
            d = Double.MAX_VALUE/i+1;
        }
        for(int j=1;j<11;j++)
        {
            System.out.println(Thread.currentThread().getName() + "循环了" + j +"次");
            if(j==5)
            {
                sleepThread(Thread.currentThread(),5000);
            }
        }
        System.out.println("线程体执行完毕"); //死亡状态
    }
    public static void sleepThread(Thread t,long time)
    {
        if(t.isAlive())
            try {
                System.out.println("线程开始休眠");
                t.sleep(time);
                System.out.println("线程已醒,返回到就绪状态");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
    
    /**
     * 挂起一个线程t
     * @param t
     */
    @SuppressWarnings("deprecation")
    public static  void suspendThread(Thread t)
    {
        //判断线程是否处于活动状态 ,指的就是就绪状态
        if(t.isAlive())
        {
            t.suspend();
            
            System.out.println("线程已挂起");
        }
    }
    /**
     * 恢复被挂起的线程
     * @param t
     */
    public static void resumeThread(Thread t)
    {
        if(!t.isInterrupted())
        {
            t.resume();
            System.out.println("线程已恢复!");
        }
    }
    
    public static void main(String args[])
    {
        SuspendThread st = new SuspendThread("A#");//创建状态
        st.start();//就绪状态
        
        //suspendThread(st);//阻塞状态 --挂起
        //resumeThread(st);//将挂起的线程恢复,线程又重新进入了就绪状态
    }
}

几个复杂的方法:
isAlive():是否处于活动状态,活动状态指的是从启动到死亡之间的时刻。
yield():一个正在运行的线程调用该方法后,失去CPU的控制权,重新和其他处于就绪状态的线程争抢CPU的控制权。
public class YieldThread extends Thread{
    public YieldThread(String name)
    {
        super(name);
    }
    public void run()
    {
    
        for(int j=1;j<11;j++)
        {
            System.out.println(Thread.currentThread().getName() + "循环了" + j +"次");    
            if(j==3)
            {
                //让当前正在运行的线程放弃CPU的控制权
                Thread.currentThread().yield();
            }
        }
    }

    public static void main(String[] args) {
        for(int i=1;i<6;i++)
        {
            new YieldThread(i+"#").start();
        }

    }
}

join():让其他处于就绪状态的线程等待当前正在执行的线程。A正在执行B.join(long t)方法,B线程加入,其他线程待B执行完毕或者执行t毫秒后再执行。
public class JoinTest extends Thread{

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
        JoinTest t1 = new JoinTest("T1");
        JoinTest t3 = new JoinTest("T3");
        JoinTest t2 = new JoinTest("T2");
        t3.start();
        t1.start();
        t2.start();
        try {
            t2.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }    
    }

    public JoinTest(String name)
    {
        super(name);
    }

    public void run()
    {
        System.out.println(this.getName() + "线程开始执行,当前时间:" + System.currentTimeMillis());
        for(int i=1;i<6;i++)
        {        
            System.out.println(this.getName() + "循环体循环了" + i + "次");
        }
        System.out.println(this.getName() + "线程执行结束,当前时间:" + System.currentTimeMillis());        
    }
}

interrupt():中断一个线程。无论线程处于中断状态与否,isAlive()方法总是返回true.
interrupted():判断线程是否处于中断状态,如是中断状态返回true,并且将终止中断状态,返回到就绪状态。

isInterrupted():判断线程是否处于中断状态,如是中断状态返回true,否则false。并且当前线程的中断状态不会被清除。

public class SuspendThread extends Thread {
    //定义构造方法
    public SuspendThread(String name)
    {
        super(name);
    }
    //线程 体
    public void run()
    {
        System.out.println("线程体开始执行");
        for(int i=0;i<1000000;i++)
        {
            double d = 10;
            d = Double.MAX_VALUE/i+1;
        }
        for(int j=1;j<11;j++)
        {
            System.out.println(Thread.currentThread().getName() + "循环了" + j +"次");
            if(j==5)
            {
                //sleepThread(Thread.currentThread(),5000);
            }
        }
        System.out.println("线程体执行完毕"); //死亡状态
    }
    public static void sleepThread(Thread t,long time)
    {
        if(t.isAlive())
            try {
                System.out.println("线程开始休眠");
                t.sleep(time);
                System.out.println("线程已醒,返回到就绪状态");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
    
    /**
     * 挂起一个线程t
     * @param t
     * @throws InterruptedException 
     */
    @SuppressWarnings("deprecation")
    public static void suspendThread(Thread t) 
    {
        
        //判断线程是否处于活动状态 ,指的就是创建状态到死亡之间时段
        if(t.isAlive())
        {
            t.interrupt();
            System.out.println("是否处于活动状态?" + t.isAlive());
            System.out.println("线程已挂起");
        }
    }
    /**
     * 恢复被挂起的线程
     * @param t
     */
    public static void resumeThread(Thread t)
    {
        if(t.isInterrupted()) //true
        {
            t.interrupted(); //清除中断
            
            System.out.println("线程已恢复!");
        }
    }
    
    public static void main(String args[])
    {
        SuspendThread st = new SuspendThread("A#");//创建状态
        st.start();//就绪状态
        
        suspendThread(st);//阻塞状态 --挂起
        resumeThread(st);//将挂起的线程恢复,线程又重新进入了就绪状态
    
    }
}

5、线程的优先级
线程的优先级分为10个等级:1-10,1最低,10最高。Java的Thread类同时提供了3个常量表示优先级:MIN_PRIORITY (1), NORM_PRIORITY(5),MAX_PRIORITY(10),推荐为线程设置优先级时使用常量不要用数字。
线程的默认优先级是5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值