【线程】Java线程(1)-线程基本理解and实现方式
2014-04-22 15:28
337 查看
1、关于进程和线程,在知乎上看到一个很漂亮的解释。
【来源:pansz,自由软件开发者,地址:多线程有什么用?(CSDN禁用了知乎的URL,为什么?)】1。单进程单线程:一个人在一个桌子上吃菜。
2。单进程多线程:多个人在同一个桌子上一起吃菜。
3。多进程单线程:多个人每个人在自己的桌子上吃菜。
多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。。。此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。
1。对于 Windows 系统来说,【开桌子】的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜。因此 Windows 多线程学习重点是要大量面对资源争抢与同步方面的问题。
2。对于 Linux 系统来说,【开桌子】的开销很小,因此 Linux 鼓励大家尽量每个人都开自己的桌子吃菜。这带来新的问题是:坐在两张不同的桌子上,说话不方便。因此,Linux 下的学习重点大家要学习进程间通讯的方法。
--
补充:有人对这个开桌子的开销很有兴趣。我把这个问题推广说开一下。
开桌子的意思是指创建进程。开销这里主要指的是时间开销。
可以做个实验:创建一个进程,在进程中往内存写若干数据,然后读出该数据,然后退出。此过程重复 1000 次,相当于创建/销毁进程 1000 次。在我机器上的测试结果是:
UbuntuLinux:耗时 0.8 秒
Windows7:耗时 79.8 秒
两者开销大约相差一百倍。
这意味着,在 Windows 中,进程创建的开销不容忽视。换句话说就是,Windows 编程中不建议你创建进程,如果你的程序架构需要大量创建进程,那么最好是切换到 Linux 系统。
大量创建进程的典型例子有两个,一个是 gnu autotools 工具链,用于编译很多开源代码的,他们在 Windows 下编译速度会很慢,因此软件开发人员最好是避免使用 Windows。另一个是服务器,某些服务器框架依靠大量创建进程来干活,甚至是对每个用户请求就创建一个进程,这些服务器在 Windows 下运行的效率就会很差。这"可能"也 是放眼全世界范围,Linux 服务器远远多于 Windows 服务器的原因。
浏览器浏览一个页面,里面有很多图片,多线程,每个线程下载一副图片,他们相当于一个桌子上不同的菜。
浏览器开了多个标签浏览不同网站,多进程,因为他们相当于"不同的桌子"。
2、线程的实现方式
1)、继承Thread。public class ExtendsThread extends Thread{ public void run(){ System.out.println("继承Thread实现线程"); } }2)、实现Runable()接口。
public class ImplRunable implements Runnable{ public void run() { System.out.println("实现Runable实现线程"); } }本质都需要重写run方法。
Test类
public class Test { public static void main(String[] args) { Thread exThread = new ExtendsThread(); exThread.start(); Thread imtThread = new Thread(new ImplRunable()); imtThread.start(); } }两种实现方式也经常可以这样写:
new Thread(){ public void run(){ System.out.println("继承Thread实现线程"); } }.start(); new Thread(new Runnable() { public void run() { System.out.println("实现Runable实现线程"); } }).start();
3、两种实现方式的区别
Thread是类,而Runnable是接口;Thread本身是实现了Runnable接口的类。我们知道"一个类只能有一个父类,但是却能实现多个接口",因此Runnable具有更好的扩展性。此外,Runnable还可以用于"资源的共享"。即,多个线程都是基于某一个Runnable对象建立的,它们会共享Runnable对象上的资源。
通常,建议通过"Runnable"实现多线程!
关于共享资源,举例说明:
1)、impl Runable实现
public class RunThread implements Runnable{ private int money = 100; public void run() { for (int i = 1; i <= 5; i++) { money--; System.out.println(Thread.currentThread().getName()+" "+money); } } }
虽然两个线程可能不是依次执行的,但是最后结果是90。因为两个线程处理的是一个变量。
2)、extends Thread实现
public class ExThread extends Thread{ private int money = 100; public void run() { for (int i = 1; i <= 5; i++) { money--; System.out.println(Thread.currentThread().getName()+" "+money); } } }
最后的结果是95,两个线程处理的是各自的变量。
Main.Java(测试类)
public class Main { public static void main(String[] args) { RunThread thread = new RunThread(); new Thread(thread, "1").start(); new Thread(thread, "2").start(); ExThread exThread1 = new ExThread(); exThread1.start(); ExThread exThread2 = new ExThread(); exThread2.start(); } }
4、关于Thread
回到Java API,看看关于Thread的说明:public class Thread extends Object implements RunnableRunable是一个接口,如果针对线程直接调用run,和普通方法无异。
查看Thread.start()方法,
public synchronized void start() { if (started) throw new IllegalThreadStateException(); started = true; group.add(this); start0(); } private native void start0();做了同步处理,并且如果线程已经启动,会抛出IllegalThreadStateException异常。
否则的话,在内部调用了start0方法,查看该方法,native,和操作系统做了交互。
【参考】:(URL被csdn禁用了)
1、pansz,自由软件开发者,地址:多线程有什么用?
2、Java多线程系列--"基础篇"02之 常用的实现多线程的两种方式
相关文章推荐
- 深入理解JVM-Java线程-实现方式,线程调度,状态
- Java线程间通信-回调的实现方式
- java 实现多线程的三种基本方式
- java实现线程的两种方式
- JAVA中实现线程的三种方式
- JAVA多线程之——线程的实现方式
- Java多线程系列-实现多线程的最基本两种方式
- java中的线程实现的两种方式
- JAVA_SE线程实现两种方式实例
- java中进程与线程_三种实现方式总结(必看篇)
- Java实现线程的3种方式
- 我的java笔记——启动线程的基本方式
- JAVA 线程的两种基本实现方法(继承Thread类和实现Runnable接口)
- JAVA多线程之——线程的实现方式
- java线程实现的两个方式
- java的两种线程实现方式
- java多线程 -- 创建线程的第三者方式 实现Callable接口
- JAVA多线程之——线程的实现方式
- Java线程的实现方式
- java中兩種实现线程的方式