首页 > 技术文章 > 多线程

dengheng 2016-08-23 13:25 原文

为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?

这是另一个非常经典的java多线程面试问题。这也是我刚开始写线程程序时候的困惑。现在这个问题通常在电话面试或者是在初中级Java

面试的第一轮被问到。这个问题的回答应该是这样的,当你调用start()方法时你将创建新的线程,并且执行在run()方法里的代码。但是如果你直接调用run()方法,不会创建新的线程也不会执行调用线程的代码。就是说想要启动线程就必须用start() 方法

http://www.56.com/u74/v_MTA4MTI4MTI3.html
 
线程: 是一个程序不同的执行路径  进程里面包含线程 
                                       单线程                                           和                           多线程?
main 就是一个主线程 
cpu为什么执行多个线程?
在同一个cpu里面只能执行一个线程 至于为什么能够执行多线程 其实cpu里面会把一个时间段分为一个个时间片当两个或多个线程执行的时候cpu会把时间片分给A线程一片 B线程一片 A线程一片 B线程一片 至于再分的时候怎么控制时间片的大小是用线程里面的优先级控制的
并且cpu的执行速度非常快 所以在咱们人类看好比执行的是多个
 
创建线程类 
   创建线程类的方式有两种 :
               继承Extends Thread类
               实现Implem Runnabale类  其实Threat 类里面也是实现Runnable接口 
  至于他们有什么区别 
               还是用实现Runnable 比较好 按照java语言的编程思想单继承多实现 用实现Runnable灵活性比较大
               还有就是在启动的时候 
                           要是继承了Threat类 启动方式 直接 线程类.start();方法启动
                           要是实现了Runanble接口 要把该线程类放到Threat类里面 然后在启动
 
 
1. Treat.spleet();
睡眠 让一个线程睡眠 该方法在哪个线程里面那个线程睡眠    要try catch一下 
至于为什么try catch 因为在线程睡眠的 时候 要是被其他线程打断的话就会抛出异常     
2. interrupt()打断睡眠线程的方法。                
storp()。 停止线程 !  尽量不要使用。 安全性低 , 比如在线程运行的时候直接停止 。 这样就把线程杀死了 这样线程里面需要关闭的东西就关闭不掉 了。
   在死锁的时候锁的特别厉害的时候 直接strop() 不妨也是一种解决死锁的方法;
join() ; 线程合并 ! 两个线程合并成一个线程; 就好比是一个线程执行
 
yield() ;线程礼让 就是把cpu的资源(时间片)让给其他前程使用;
 
线程的优先级;
   线程的优先级越高 在cpu执行时间片就越长 ;一般线程默认的5;
    thread1.setPriority(thread1.NORM_PRIORITY+3);
Thread.currentThread();获取当前的线程
Thread.currentThread().isAlive();  线程是否还活着返回
 
 
线程同步:线程在一个线程访问资源的时候 其他线程不能使用该资源, 就好加上一把锁 !
      锁定的方式有两种: 
                        一方式 : 锁定一段代码 
                                    这里面的代码被锁定了就是说当一个线程访问被锁定代码的时候不能有另一个线程访问被锁定的代码
  public void test() {            
     Synchronized(this){ 
          这里面的代码被锁定了
      } 
}              
          
                      二方式:方法上加锁锁定当前的方法 
                                    当一个线程访问该方法的时候 另一个线程不能访问该方法 这和第一个锁定代码块还不一样 锁定范围要比第一种的大! 其实这也是一种解决线程死锁的一种方式!
          public Synchronized void test() {            
               这整个方法被的方法被锁了
           }
  线程死锁!
    两个或者多个线程之间相互等待,导致线程都无法执行,叫做线程死锁。

            产生死锁的条件:
                1.有至少一个资源不能共享  
                2.至少有一个任务必须持有一个资源并且等待获取另一个被别的任务持有的资源
                3.资源不能任务抢占
                4.必须有循环等待
                         
 
线程死锁解释: 就是在你的线程一中锁定了两个对象 对象一和对象二 而线程二 也要锁定对象二和对象一   当两个线程执行的时候线程一 锁定了对象一 这时在锁定对象二 这个线程线程一就走完了 但与此同时线程二锁定了对象二 这样线程一就不能锁住线程二 这样线程一就不能走完  线程一走不完对象一就不能释放 对象一不能释放 线程二就不能走完 这样两个线程就僵持在这里 都不能执行
 
线程死锁的解决方式:
          1. 所有线程都按顺序获取资源,比如资源ABCD ,那所有线程必须获取了A资源再去 申请B资源 , 类推
                 但是给资源合理编号也是件难事
           2. 增大线程的粒度  把锁定的对象放大
 
wait() 和 sleep() 区别:         

       1、这两个方法来自不同的类分别是Thread(spleep())和Object(wait())

  2、最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

        3、wait() 只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)

推荐阅读