Java简明教程 12.多线程(multithreading)
单线程和多线程
关于它们的区别,zhihu上有一个回答,我认为十分不错,如下:
- . 单进程单线程:一个人在一个桌子上吃菜。
- . 单进程多线程:多个人在同一个桌子上一起吃菜。
- . 多进程单线程:多个人每个人在自己的桌子上吃菜。
- 多线程的问题是多个人同时吃一道菜的时候容易发生争抢.例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。
- 例子:
- 多线程:
- 浏览器浏览一个页面,里面有很多图片,多线程,每个线程下载一副图片,他们相当于一个桌子上不同的菜。
- 多进程:
- 浏览器开了多个标签浏览不同网站,多进程,因为他们相当于“不同的桌子”
- 原文链接:http://www.zhihu.com/question/19901763
如何创建线程
方式1:
MultiThreading.java
- public class MultiThreading {
- public static void main(String[] args) {
- NewThread thread1 = new NewThread();
- NewThread thread2 = new NewThread();
- thread1.start();
- thread2.start();
- }
- }
- class NewThread extends Thread { //继承Thread类
- private static int num = 0;
- public NewThread() {
- super("THread:" + ++num); //通过Thraed的构造方法,初始化线程的名字
- //public Thread(String name)
- }
- //重写Thread的run()方法,然后通过Thread的start()方法调用run()方法,实现多线程
- @Override
- public void run() {
- while (true) {
- System.out.println(super.getName() + " is running~");//getName():获取线程的名字
- }
- }
- }
方式2:实现Runnable接口
MultiThreading2.java
- public class MultiThreading2 {
- public static void main(String[] args) {
- Thread thread1 = new Thread(new NewThread("线程1"));
- Thread thread2 = new Thread(new NewThread("线程2"));
- thread1.start();
- thread2.start();
- }
- }
- class NewThread implements Runnable {
- private String threadName = null;
- public NewThread(String threadName) {
- this.threadName = threadName;
- }
- @Override
- public void run() {
- while (true) {
- System.out.println(this.threadName + " is running~");
- }
- }
- }
看下Thread类的构造方法, "public Thread(Runnable target)", 不难懂上面那个小例子.
synchronized
我们考虑一个问题,如果一个桌子上有三个人(Person)在吃100个汉堡包(Hamburger), 当只有一个汉堡包的时候,其中的一个人判断还有一个汉堡包(hamburgerNum > 0), 所以执行了eatHamburger()操作, 而另一个人在这之前,也判断了还有一个汉堡包(hamburgerNum > 0), 想要执行eatHamburger()操作的时候, 那个汉堡包已经被别人吃了, 那么这个时候 (hamburgerNum--) 汉堡包的数量不就成了负数了吗? 这明显是不行的.
也就是说, "判断和吃"这个两个操作, 需要一个人一起执行成功后, 才能让另一个人执行. 所以我们需要把它们 "绑在一起", 也就是"锁"起来.这里就不要用到 "syncronized"(同步)这个修饰符了
Test.java
- public class Test {
- public static void main(String[] args) {
- Hamburger h = new Hamburger(100);
- Person p1 = new Person(h);
- Person p2 = new Person(h);
- Person p3 = new Person(h);
- p1.start();
- p2.start();
- p3.start();
- }
- }
- class Person extends Thread { //继承Thread类,重写run()方法,通过调用Thread的start()方法,创建多个线程
- private int count = 0; //记录这个人吃了多少个汉堡包
- private String name = "小明";
- private static int num = 0; //这里需要使用static修饰
- private Hamburger hamburger = null;
- public Person(Hamburger hamburger) {
- this.hamburger = hamburger;
- this.name = this.name + (++num) + "号";
- }
- @Override
- public void run() {
- while (true) {
- if (hamburger.eatHambergerNum()) {
- System.out.println(this.name + ": eat 1 Hamburger.");
- count++;
- try {
- sleep((int)Math.random() * 100); //鄙人不明白为什么要这个句子?如果知道的请告知
- //或者,不需要这个句子?比人测试了,这个句子似乎没什么作用
- //线程不管"sleep"不"sleep",都不会永远分配给进程的霸占cpu吧
- } catch(InterruptedException e) {
- e.printStackTrace();
- }
- } else {
- break;
- }
- }
- System.out.println(this.name + ": " + count);
- }
- }
- class Hamburger {
- private int hamburgerNum = 0;
- public Hamburger(int num) {
- this.hamburgerNum = num;
- }
- //注意这里使用了 "synchronized"修饰! "synchronized"也可以修饰语句块 用法: synchronized(对象) {}
- public synchronized boolean eatHambergerNum() {
- if (hamburgerNum > 0) {
- hamburgerNum--;
- return true;
- } else {
- return false;
- }
- }
- }
参考:http://www.cnblogs.com/vamei/archive/2013/04/15/3000898.html
Java简明教程 12.多线程(multithreading)的更多相关文章
- Java基础教程:多线程基础(1)——基础操作
Java:多线程基础(1) 实现多线程的两种方式 1.继承Thread类 public class myThread extends Thread { /** * 继承Thread类,重写RUN方法. ...
- Java基础教程:多线程基础(4)——Lock的使用
Java基础教程:多线程基础(4)——Lock的使用 快速开始 Java 5中Lock对象的也能实现同步的效果,而且在使用上更加方便. 本节重点的2个知识点是:ReentrantLock类的使用和Re ...
- Java基础教程:多线程基础(2)——线程间的通信
Java基础教程:多线程基础(2)——线程间的通信 使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控与监督. 线程间的通信 ...
- Java基础教程:多线程基础——线程池
Java基础教程:多线程基础——线程池 线程池 在正常负载的情况瞎,通过为每一个请求创建一个新的线程来提供服务,从而实现更高的响应性. new Thread(runnable).start() 在生产 ...
- Java基础教程:多线程杂谈——双重检查锁与Volatile
Java基础教程:多线程杂谈——双重检查锁与Volatile 双重检查锁 有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化.此时程序员可能会采用延迟初始化.但要正确实 ...
- Java基础教程:多线程基础(6)——信号量(Semaphore)
Java基础教程:多线程基础(6)——信号量(Semaphore) 信号量 信号量(Semaphore)由一个值和一个指针组成,指针指向等待该信号量的进程.信号量的值表示相应资源的使用情况.信号量S≥ ...
- Java基础教程:多线程基础(5)——倒计时器(CountDownLatch)
Java基础教程:多线程基础(5)——倒计时器(CountDownLatch) 引入倒计时器 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种 ...
- Java 简明教程
本文为 Java 的快速简明教程,主要用于快速了解.学习和复习java的语法特点. // 单行注释 /* 多行注释 */ /** JavaDoc(Java文档)注释是这样的.可以用来描述类和类的属性. ...
- Java基础教程(12)--深入理解类
一.方法的返回值 当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...
随机推荐
- GPU && CUDA:主机和设备间数据传输测试
数据传输测试,先从主机传输到设备,再在设备内传输,再从设备传输到主机. H-->D D-->D D-->H // moveArrays.cu // // demonstrates C ...
- Spring学习记录(二)
1.Spring中的AOP思想 aop思想:横向重复,纵向抽取. AOP(Aspect-OrientedProgramming,面向切面编程),AOP包括切面(Aspect),通知(Advice),连 ...
- 关于小程序 input 组件内容显示不全(显示的长度不满 input 宽度)问题
问题:小程序的input组件经常用到,但在使用input组件的时候会出现一种现象:明明设置了input的宽度,但是输入的内容显示的长度范围却怎么都不到一整个input组件的宽度,而且后面没显示的地方无 ...
- Linux Shell 几个特殊符号命令 & 、&& 、 ||
& 放在启动参数后面表示设置此进程为后台进程 默认情况下,进程是前台进程,这时就把Shell给占据了,我们无法进行其他操作,对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动 ...
- Django项目中"expected str, bytes or os.PathLike object, not list"错误解决:
对于这个错误,也在于自己对django基础的掌握不是很牢固,忽略了MEDIA_ROOT的类型是string,而不是list. 错误的写法: MEDIA_ROOT = [ os.path.join(BA ...
- php短网址生成算法
<?php //短网址生成算法 class ShortUrl { //字符表 public static $charset = "0123456789ABCDEFGHIJKLMNOPQ ...
- 科学计算库Numpy——随机模块
np.random.rand() 随机生成一个[0,1)之间的浮点数. 参数表示数组的维数 np.random.randint() 生成一个随机的整数数组. 备注:生成一个5*4的二维数组,数组中的每 ...
- Union found
Use array. class UnionFound { public: vector<int> v; int cnt; UnionFound(int n) { v = vector&l ...
- 谭浩强C第四版(p141)16.输出以下图案
运行结果: * *** ***** ******* ***** *** * Press any key to continue #include<stdio.h> int main() { ...
- hihocoder#1098 : 最小生成树二·Kruscal算法
#1098 : 最小生成树二·Kruscal算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 随着小Hi拥有城市数目的增加,在之间所使用的Prim算法已经无法继续使用 ...