http://itmian.com/2011/05/11/java%e9%9d%a2%e8%af%95%e9%a2%98-%e5%a4%9a%e7%ba%bf%e7%a8%8b/
Java程序员面试中的多线程问题:
http://sd.csdn.net/a/20120528/2806046.html
1、线程:
一般我们开发的程序都是只有一个主线程的,即MAIN()函数开始,但是在一些特别的场合下,比如服务器接受命令的过程,可能需要同时处理多个客户端发送的命令,这时就需要征对每个客户建立一个线程 。这样建立多线程程序,多线程可以使得在同一时间间隔内,执行多个指令,以至于多个逻辑处理并发的运行。
在JAVA中有二种方法可以定义一个线程:Runnable接口与Thread类,最终都是由Thread类的 start()方法启动线程,而真正执行的命令在run()方法中 ,另外线程有几种状态:执行,终止,休眠,挂起等。在某种条件下各个状态之间可以互相转换。
一个线程结束的标志是:run()方法结束。
一个锁被释放的标志是:synchronized块或方法结束
值得注意的是:线程的在被激活后不一定马上就运行,而是进入到可运行线程的队列中。
2、进程和线程的区别
通俗一点说,进程就是程序的一次执行,而线程可以理解为进程中的执行的一段程序片段。
用一点文词说就是,每个进程都有独立的数据空间 (进程上下文);而线程可以看成是轻量级的进程。
一般来讲(不使用特 殊技术),同一进程所产生的线程共享同一块内存空间 。
同一进程中的两段代码是不可能同时执行的,除非引入线程。
线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除 。
线程占用的资源要少于进程所占用的资源。
进程和线程都可以有优先级。
在线程系统中进程也是一个线程。可以将进程理解为一个程序的第一个线程。
多进程-----在操作系统中,能同时运行多个任务(程序)。
多线程-----在同一应用程序中,有多个顺序流同时执行。
3、两种线程模型
4、实现Runnable接口相对于继承Thread类来说,有如下显著的好处:
(1)适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码,数据有效的分离,较好地体现了面向对象的设计思想。
(2)可以避免由于Java的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable接口的方式了。
(3)有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的 。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程操作相同的数据,与它们的代码无关。当共享访问相同的对象时,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数 实参传递进去,这个对象就是一个实现了Runnable接口 的类的实例。
通过铁路售票程序来理解实现多线程:
一个线程对象只能启动一个线程,无论你调用多少遍start()方法,结果只有一个线程。
public class ThreadDemo1{ public static void main(String[] args){ ThreadTest t = new ThreadTest(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } } class ThreadTest implements Runnable{ private int tickets = 5; public void run(){ while(true){ if(tickets > 0){ System.out.println(Thread.currentThread().getName() +" is saling ticket "); tickets--; } } } }
JAVA多线程基础:http://tomyz0223.iteye.com/blog/1001778
关于守护线程:
对于Thread来说只想说两个方法,一个是setDaemon(false|true),另一个是join()。首先说说守护线程,这么东西是干什么用的?对于Java应用我们都知道main方法是入口,它的运行代表着主线程开始工作了,我们也知道JVM里面有垃圾回收器的存在使得我们放心让main飞奔,然而这背后的故事是垃圾回收线程作为守护着主线程的守护线程默默的付出着。。。很像那个啥啊,呵呵。令人发指的是main这个畜生背后其实有好几个守护线程默默的付出!当然如果硬是要把守护线程比做女人,非守护线程比做男人的话,那么一个男人背后可以有多个默默付出的女人。Java在设计时就默认了这个现实社会不太能实现的现实,并且强制规定如果男人不在了,这个虚拟世界就over了,看来资本主义社会下长大的孩子创造的东西骨子里是封建社会的血脉啊!扯远了,对的,JVM内部的实现是如果运行的程序只剩下守护线程的话,程序将终止运行,直接结束。所以守护线程是作为辅助线程存在的,主要的作用是提供计数等等辅助的功能。下面写个小例子说明一下:
这个例子的结果是main主线程睡两秒之后说再见,而子线程则是在这两秒内计计数然后跟着一起说再见。当然它很不情愿,因为它想计10秒,但是没机会。把t.setDaemonThread(true)注释掉你会看到主线程说再见了,但是子线程快快乐乐的计完数说再见。这就是守护线程的作用,一切以非守护线程为主!很痴情啊,哈哈。
来源:http://yanxuxin.iteye.com/blog/547266
两种线程对象的区别:
在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent)。而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel)。
在JAVA中,要开始一个线程,有两种方式。一是直接调用Thread实例的start()方法,二是将Runable实例传给一个Thread实例然后调用它的start()方法。
在前面已经说过,线程对象和线程是两个完全不同的概念。这里我们再次深入一下,生成一个线程的实例,并不代表启动了线程。而启动线程是说在某个线程对象上启动了该实例对应的线程,当该线程结束后,并不会就立即消失。
本节重点要说的是两种线程对象产生线程方式的区别。
class MyThread extends Thread{ } |
public class Test { public static void main(String[] args) throws Exception{ MyThread mt = new MyThread(); mt.start(); } } |
public class Test { public static void main(String[] args) throws Exception{ MyThread mt = new MyThread(); mt.start(); System.out.println(101); } } |
public class Test { public static void main(String[] args) throws Exception{ MyThread mt = new MyThread(); mt.start(); mt.join(); System.out.println(101); } } |
public class Test { public static void main(String[] args) throws Exception{ MyThread mt = new MyThread(); mt.start(); mt.join(); Thread.sleep(3000); mt.start(); } } |
public synchronized void start() { if (started) throw new IllegalThreadStateException(); started = true; group.add(this); start0(); } |
class R implements Runnable{ private int x = 0; public void run(){ for(int i=0;i<100;i++){ try{ Thread.sleep(10); }catch(Exception e){} System.out.println(x++); } } } |
public class Test { public static void main(String[] args) throws Exception{ new Thread(new R()).start(); } } |
public class Test { public static void main(String[] args) throws Exception{ R r = new R(); for(int i=0;i<10;i++) new Thread(r).start(); } } |
package debug; import java.io.*; import java.lang.Thread; class MyThread extends Thread{ public int x = 0; public void run(){ System.out.println(++x); } } class R implements Runnable{ private int x = 0; public void run(){ System.out.println(++x); } } public class Test { public static void main(String[] args) throws Exception{ for(int i=0;i<10;i++){ Thread t = new MyThread(); t.start(); } Thread.sleep(10000);//让上面的线程运行完成 R r = new R(); for(int i=0;i<10;i++){ Thread t = new Thread(r); t.start(); } } } |
来源:http://dev.yesky.com/186/2547686.shtml