黑马程序员技术交流社区

标题: 线程问题 [打印本页]

作者: linder_qzy    时间: 2015-3-6 14:22
标题: 线程问题
今天看到网上看到一面试题,感觉很简单可自己想想又不知道怎么回答好。

请描述java线程的生命周期? 线程同步是怎么回事? 如何同步?
作者: 邓士林    时间: 2015-3-6 14:25
你就解释就行了
作者: 笑望长空,逆转    时间: 2015-3-6 14:38
新建-就绪-(阻塞)-运行--死亡

其中当用new 创建完一个线程对象后,该线程处于新建状态

    当线程对象调用了start()后,该线程处于就绪状态
  
    如果处于就绪状态的线程获得CPU时间片,开始执行run方法的线程执行体,该线程处于运行状态

   如果线程调用了sleep()或者调用了一个阻塞式IO方法等,该线程处于阻塞状态

   如果线程的run()执行完成或者抛出一个未捕获的异常等原因,该线程处于死亡状态

线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。
当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。
线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。

线程同步的方法
(1)wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
(2)sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉  
  InterruptedException异常。
(3)notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的
  唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
(4)notityAll ():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,
  而是让它们竞争.
作者: 艺多不压身丶    时间: 2015-3-6 14:46
进程:正在进行中的程序。其实进程就是一个应用程序运行时的内存分配空间。
线程:其实就是进程中一个程序执行控制单元,一条执行路径。进程负责的是应用程序的空间的标示。线程负责的是应用程序的执行顺序。
一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序,每个线程在栈区中都有自己的执行空间,自己的方法区、自己的变量。
jvm在启动的时,首先有一个主线程,负责程序的执行,调用的是main函数。主线程执行的代码都在main方法中。
当产生垃圾时,收垃圾的动作,是不需要主线程来完成,因为这样,会出现主线程中的代码执行会停止,会去运行垃圾回收器代码,效率较低,所以由单独一个线程来负责垃圾回收。
随机性的原理:因为cpu的快速切换造成,哪个线程获取到了cpu的执行权,哪个线程就执行。
线程状态:
被创建:start()
运行:具备执行资格,同时具备执行权;
冻结:sleep(time),wait()—notify()唤醒;线程释放了执行权,同时释放执行资格;
临时阻塞状态:线程具备cpu的执行资格,没有cpu的执行权;
消亡:stop()
同步代码块。
格式:
synchronized(对象) {  // 任意对象都可以。这个对象就是锁。
        需要被同步的代码;
}
  1. package pack;
  2. // 同步死锁:通常只要将同步进行嵌套,就可以看到现象。
  3. // 同步函数中有同步代码块,同步代码块中还有同步函数。
  4. class MyLock{
  5.         static Object locka=new Object();
  6.         static Object lockb=new Object();
  7. }
  8. class Test implements Runnable{
  9.         private boolean flag;
  10.         Test(boolean flag){
  11.                 this.flag=flag;
  12.         }
  13.         public void run(){
  14.                 if(flag){
  15.                         synchronized(MyLock.locka){
  16.                                 System.out.println("ifif-locka");
  17.                                 synchronized(MyLock.lockb){
  18.                                         System.out.println("ifif-lockb");
  19.                                 }
  20.                         }
  21.                 }
  22.                 else{
  23.                         synchronized(MyLock.lockb){
  24.                                 System.out.println("else-lockb");
  25.                                 synchronized(MyLock.locka){
  26.                                         System.out.println("else-locka");
  27.                                 }
  28.                         }
  29.                 }
  30.         }
  31. }
  32. class DeadLockTest{
  33.         public static void main(String[] args){
  34.                 Thread t1=new Thread(new Test(true));
  35.                 Thread t2=new Thread(new Test(false));
  36.                 t1.start();t2.start();
  37.         }
  38. }[code]package pack;
  39. // 同步:解决线程安全问题。
  40. // 弊端:相对降低性能,因为判断锁需要消耗资源,产生了死锁。
  41. // 定义同步是有前提的:
  42.         // 1,必须要有两个或者两个以上的线程,才需要同步。
  43.         // 2,多个线程必须保证使用的是同一个锁。
  44. // 同步函数:其实就是将同步关键字定义在函数上,让函数具备了同步性。
  45. // 同步函数所使用的锁都是this,因为函数都有自己所属的对象。
  46. // 同步代码块使用的锁可以是任意对象。
  47. // 同步函数使用的锁是this,静态同步函数的锁是该类的字节码文件对象。
  48. class Ticket implements Runnable{
  49.         private int tick=100;
  50.         private Object obj=new Object();
  51.         boolean flag=true;
  52.         public void run(){
  53.                 if(flag){
  54.                         while(true){
  55.                                 synchronized(obj){
  56.                                         if(tick>0)
  57.                                                 System.out.println(Thread.currentThread().getName()+"code:"+tick--);
  58.                                 }
  59.                         }
  60.                 }else
  61.                         while(true)
  62.                                 this.show();
  63.         }
  64.         public synchronized void show(){
  65.                 if(tick>0){
  66.                         System.out.println(Thread.currentThread().getName()+"show:"+tick--);
  67.                 }
  68.         }
  69. }
  70. class TicketDemo2{
  71.         public static void main(String[] args){
  72.                 Ticket t=new Ticket();
  73.                 Thread t1=new Thread(t);
  74.                 Thread t2=new Thread(t);
  75.                 t1.start();
  76.                 t.flag=false;
  77.                 t2.start();
  78.         }
  79. }
复制代码
[/code]
作者: 几米丶    时间: 2015-3-6 15:56
楼下 介绍的很好啊
作者: linder_qzy    时间: 2015-3-7 00:15
艺多不压身丶 发表于 2015-3-6 14:46
进程:正在进行中的程序。其实进程就是一个应用程序运行时的内存分配空间。
线程:其实就是进程中一个程序 ...

回答好详细啊 谢谢了啊
作者: linder_qzy    时间: 2015-3-7 00:16
笑望长空,逆转 发表于 2015-3-6 14:38
新建-就绪-(阻塞)-运行--死亡

其中当用new 创建完一个线程对象后,该线程处于新建状态

回答好详细啊 谢谢了啊
作者: 执念    时间: 2015-3-7 23:41
艺多不压身丶 发表于 2015-3-6 14:46
进程:正在进行中的程序。其实进程就是一个应用程序运行时的内存分配空间。
线程:其实就是进程中一个程序 ...

很给力、顶一个
作者: 浦原氏之喵    时间: 2015-3-8 15:38
MarkMarkMarkMark
作者: BEIKOU    时间: 2015-3-8 21:10
很给力,顶一下




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2