黑马程序员:java基础知识(多线程)

来源:互联网 发布:淘宝店铺被监控 编辑:程序博客网 时间:2024/05/17 23:47

---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------

java基础——多线程

1、进程和线程:
    所谓进程,就是正在执行的程序。每个进程执行都有一个顺序,该顺序称为一个执行路径或称为一个控制单元。线程就是进程中的一个独立的控制单元,线程在控制着进程的执行。一个进程中至少有一个线程。
    java虚拟机启动时,会有一个进程“java.exe”。该进程中至少有一个线程负责java程序执行,而且这个线程的运行代码存在于main函数中,该线程被称为主线程。值得注意的是,java虚拟机启动时,不止一个线程,严格来说,应该至少有两个线程,一个是主线程,一个是垃圾回收机制的线程。

2、线程的创建方式:
  (1)继承Thread类,覆盖run方法,调用线程的start方法启动线程。start方法的作用是,启动该线程并调用run方法。
    创建方式:NewThread extends Thread
             new NewThread().start();
  (2)实现Runnable接口,实现接口中的run方法,通过Thread类,建立线程对象,将Runnable的子类对象作为一个实际参数传递给Thread的构造方法,调用Thread类的start方法,开启线程,并执行Runnable子类的run方法。这样做的原因是,run方法所属的对象是Runnable的子类对象,创建的线程要去执行这个run方法,那么,就必须明确该run方法所属的对象。
    创建方式:NewRunnable implements Runnable
              new Thread(new NewRunnable()).start();
  (3)这两种创建方式的区别:实现接口的方式,线程的执行代码存放在接口子类的run方法中;继承Thread的方式,线程的执行代码存放在Thread子类的run方法中。实现接口的方式,避免了单继承的局限性。建议使用实现接口的方式创建线程。

3、run和start的区别:
    run方法:在Thread类中就定义了一个功能,就是run方法。这个方法用于存储线程要运行的代码。
    new Thread().start():创建线程,启动线程,调用线程的run方法
    new Thread().run():创建线程,使用Thread对象调用run方法,只是普通的对象调用方法,线程并未启动。

4、多线程的运行机制
    多线程在运行时,我们往往认为是多个线程在同时运行,其实不然。因为单核CPU在某一时刻,只能执行一个线程。多个线程都在获取CPU的执行权,CPU执行到谁,谁就运行。CPU在做着高速的切换,以达到同时运行的假象。我们可以形象的把多线程的运行,看作是在互相抢夺CPU的执行权。我们在执行多线程时,发现每一次的结果都有可能不一样,这就是多线程的一个特性——随机性。哪个线程“抢到”了CPU的执行权,那个就执行,至于执行多久,CPU说了算。

5、线程的状态:
  (1)被创建:new Thread() 或 new Thread(Runnable)
  (2)运行:在被创建状态调用start方法,达到运行状态;
  (3)冻结:冻结状态又分为睡眠和等待两种状态。在运行状态执行sleep(时间)方法,会使线程进入睡眠状态,没有执行资格,直到睡眠时间到,这是可能会进入阻塞状态,或进入运行状态,由CPU决定。另外一种,在运行状态执行wait()方法时,会是进程进入等待状态,没有执行资格,直到执行了notify()方法将其唤醒,进入阻塞或运行状态。
  (4)阻塞:阻塞状态是介于运行状态和冻结状态的一个临时状态;
  (5)消亡:run()方法执行结束,或执行了stop()方法。

  图解:

进程状态


6、获取和设置线程对象的名称:
    每个线程都有自己默认的名称“Thread-编号”,编号从0开始。在Thread类中,有getName()这个方法,用于获取线程的名称。setName(Name)用于自定义线程的名称。另一种自定义线程名称的方式是,使用Thread的构造方法Thread(String name).
        ①Thread t = new Thread("t1")
        ②Thread t = new Thread(Runnable,"t1")
    Thread.currentThread():获取当前线程对象,所以通常情况下会使用,Thread.cunrrentThread().getName()这种方式来获取当前线程的名称。

7、线程安全
    有一个共享数据,有多条语句在操作它,当一个线程运行时,没有全部执行完这些操作语句时,它的执行权就被另一个线程获取,这种情况,就会导致共享数据出现错误。就出现了线程安全问题。如何解决这个问题呢?通过思考我们知道,针对共享数据,每一次只能由一个线程来操作。就是一个线程全部操作完后,其他线程才可以操作。这就是使线程同步。
    java中,针对线程安全问题提供了专业的处理——线程同步。关键字:synchronized(对象锁),括号中的对象锁的作用就是,避免多个线程同时进入执行。
    它的原理:就像门上的一把锁,当某个人获得钥匙后,进入房间,从里面反锁,别人即使得到了钥匙,也进不了门;直到里面的人出来,别人才能进去。
    这个关键字可以作为一个修饰符,修饰方法,被修饰的方法,就是一个线程同步的方法。如果修饰的是一个非静态的方法,那么它的锁就是该类的对象;如果修饰的是一个静态方法,那么它的锁就是该方法所在类的字节码文件对象(类名.class)。这个关键字也可以修饰代码块,被修饰的就是同步代码块。格式与修饰方法不同,必须指定锁。如下:
       修饰方法:
           public synchronized void show(){} //锁是该类的对象(this)
            public static synchronized void show(){} //锁是(类名.class)
       修饰代码块:
           synchronized(对象锁){ 同步代码块 }
    同步的前提:①有两个或两个以上的线程;②多个线程必须使用同一个锁。
    同步线程的好处,就是解决的线程安全问题。但也有弊端,多个线程在执行时,需要判断锁,较耗资源。
    如何判断哪些代码该同步,哪些代码不该同步?
        ①明确哪些代码是多线程运行的代码;
        ②明确共享数据;
        ③明确多线程运行代码中,哪些语句是操作共享数据的。
    通过对多线程的了解,我们发现“懒汉式”单例模式,存在线程安全问题,在多线程中使用时,需要处理一下:
        public static Single getInstance()
        {
            if(s==null)//之所以多加这一层,是减少多线程对锁的判断。
            {
                synchronized(Single.class)
                {
                    if(s==null)
                        s = new Single();
                }
            }
        }
        通过上面的处理后,就解决了线程安全问题。

    在做线程同步处理的时候,有可能会出现死锁。一个共享资源,被多种方式操作,如一个方法或代码块,如果同步的锁是不一样的,当两个线程访问该资源时,就有可能会出现死锁。死锁的例子:

public void run(){if(flag){synchronized(MyLock.locka){    //同步的锁是MyLock.lockaSystem.out.println("if locka");synchronized(MyLock.lockb){  //同步的锁是MyLock.lockbSystem.out.println("if lockb");}}}else{synchronized(MyLock.lockb){    //同步的锁是MyLock.lockbSystem.out.println("else lockb");synchronized(MyLock.locka){   //同步的锁是MyLock.lockaSystem.out.println("else locka");}}}}
               在上面这个例子中,两种访问情况使用了不同的锁,一个拿了一个锁。就相当于两个人一人拿了一支筷子,谁都吃不上饭。但即使是上面这种情况,也会出现和谐的情况,正常输出。

    在开发过程中,我们应当避免死锁发生,也就是尽量避免使用同步嵌套。对同一个资源的同步操作,一定要使用相同的锁。


---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 东西掉在成都地铁上怎么办 成都地铁上掉东西了怎么办 地铁站丢了东西怎么办 在地铁站丢了东西怎么办 没有签劳动合同不发工资怎么办 没有劳动合同辞职不给工资怎么办 地铁安检要交押金怎么办 在广州地铁上人走丢了怎么办 海尔全自动洗衣机程系乱了怎么办 河南危险化学品经营许可证怎么办 甲方不给付监理费怎么办 甲方不按合同付工程款怎么办 撞车对方全责不赔钱怎么办 电梯坏了没人修怎么办 电工超作证丢了怎么办 设计师直接找电梯厂家怎么办 研究生补助申请期限过了怎么办 我的电脑图标没了怎么办 苹果锁频密码忘了怎么办 孕妇被降职降薪怎么办 公司降职降薪员工不同意怎么办 企业因为经营不善要降薪该怎么办 调岗不降薪我该怎么办? 怀孕后强制调岗怎么办 有限公司法人变更后债务怎么办 有限公司法人跑路债务怎么办 网上买票身份信息待核验怎么办 微信买票身份核验失败怎么办 买高铁票待核验怎么办 网上购票身份待核验怎么办 b站稿件版权原因怎么办 已离职老板打电话说账有问题怎么办 开到应急刹车道怎么办 自动挡的车刹车失灵怎么办 自动挡的车如果刹车失灵怎么办 手动挡汽车刹车失灵怎么办 车辆没有年检出了交通事故怎么办 跟着大货车闯了红灯怎么办 在万家金服买的电子产品坏了怎么办 汽车被油笔画了怎么办? 挂到别人车跑了怎么办