黑马程序员_多线程

来源:互联网 发布:淘宝网上有云克药卖吗? 编辑:程序博客网 时间:2024/06/05 10:38
  多线程是java中的技术。所谓多线程就是合理利用cpu达到一个看起来像是多个程序“同时”运行的效果,其实是cpu在做着线程的快速切换。
  多线程有着专门的启动方式,开启多线程要使用start方法。
  在多线程中存在着一种后台线程,后台线程依赖前台线程,当前台线程结束后,该进程只存在后台线程的话那么这个线程将结束。
会结束。
  创建一个线程类有两种方法:
1,直接继承Thread类;
2, 实现Runnable接口,然后用new Thread(实现Runnable接口的类的对象)来产生一个线程类。
  Thread类中的setDaemon(true)设置一个线程为后台线程,该方法必须在线程启动之前调用,也就是在调用start()方法之前调用。如果一个进程中只有后台线程在运行,这个进程就会结束。
  thread1.join()的作用是把thread1所对应的线程合并到调用thread1.join()的线程中。
  yield()方法可以让当前正在运行的线程对象临时暂停,让别的线程运行。
  sleep(...)方法可以让当前正在运行的线程进入睡眠状态。
  获取和更改线程的优先级分别用Thread对象的getPriority()方法和setPriority(int newPriority)方法。线程的默认优先级的值是5。
  使用Runnable接口创建多线程,适合多个相同程序代码的线程去处理同一份资源的情况。还可以避免由于java的单继承特性带来的局限。事实上,几乎所有的多线程应用都可用Runnable接口方式。
  在多线程中,由于cpu的切换问题会造成安全隐患,为了解决安全隐患我们给某段程序“上锁”,即关键字:Synchronized。被关键字synchronized所修饰的某段程序在执行的时候只允许一个线程执行,这种线程被称之为同步。“上锁”的方法并不是只有Synchronized这一种,还可以使用ReentrantLock来自定义一个“lock”“unlock”锁。他们的区别如下:
1、ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断。如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情
   ReentrantLock获取锁定与三种方式:
    a)  lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
    b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
    c)tryLock(long timeout,TimeUnit unit),   如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
    d) lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断
2、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中
3、在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;
   Object类里面有几个方法是用于线程通信的:wait(),notify(),notifyAll()。但是这些方法只能在被synchronized修饰的方法或者代码块中调用。wait()是等待命令,notify()是唤醒最先等待的线程,notifyall()是唤醒所有等待的线程。因此使用Synchronized的时候有事会发生死锁现象,举例如下:
  String str1 = "";
  String str2 = "";


  while(true)
 {
   synchronized(str1) 
    {
       ...
      synchronized(str2)
       {
         ...
       }
       ...
    }
 }


  while(true) 
 {
    synchronized(str2)
     {
        ...
        synchronized(str1)
        {
         ...
        }
        ...
     }
  }
  在上述例子中,当两个while块里面的代码分别由两个线程执行,那么就形成了死锁。在使用多线程的时候一定要避免死锁的发生。
 

















0 0