Java面向对象   线程

知识概要:  

                (1)线程与进程

(2)自定义线程的语法结构

(3)多线程概念理解

(4)多线程状态图

(5)多线程--卖票

(6)同步函数的锁



线程与进程

进程:是一个正在执行中的程序。

            每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。

线程:就是进程中的一个独立的控制单元。

            线程在控制着进程的执行。一个进程中至少有一个线程。

Java VM  启动的时候会有一个进程java.exe.

该进程中至少一个线程负责java程序的执行。

           而且这个线程运行的代码存在于main方法中。

           该线程称之为主线程。扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程。

自定义线程的语法结构

1,如何在自定义的代码中,自定义一个线程呢?

通过对api的查找,java已经提供了对线程这类事物的描述。就Thread类。

创建线程的第一种方式:继承Thread类。

        步骤:

        1,定义类继承Thread。

        2,复写Thread类中的run方法。

             目的:将自定义代码存储在run方法。让线程运行。

3,调用线程的start方法,

             该方法两个作用:启动线程,调用run方法。

发现运行结果每一次都不同。

       因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。

       明确一点,在某一个时刻,只能有一个程序在运行。(多核除外)

       cpu在做着快速的切换,以达到看上去是同时运行的效果。

       我们可以形象把多线程的运行行为在互相抢夺cpu的执行权。

这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说的算。

为什么要覆盖run方法呢?

Thread类用于描述线程。

       该类就定义了一个功能,用于存储线程要运行的代码。该存储功能就是run方法。

也就是说Thread类中的run方法,用于存储线程要运行的代码。

  1. class Demo extends Thread
  2. {
  3. public void run()
  4. {
  5. for(int x=0; x<60; x++)
  6. System.out.println("demo run----"+x);
  7. }
  8. }
  9.  
  10. class ThreadDemo
  11. {
  12. public static void main(String[] args)
  13. {
  14. //for(int x=0; x<4000; x++)
  15. //System.out.println("Hello World!");
  16.  
  17. Demo d = new Demo();//创建好一个线程。
  18. //d.start();//开启线程并执行该线程的run方法。
  19. d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。
  20.  
  21. for(int x=0; x<60; x++)
  22. System.out.println("Hello World!--"+x);
  23.  
  24. }
  25. }

多线程的理解

自己的总结:实际上吧java的多线程可以这样理解,就拿我们自己的来说吧对于我们每个人来说,大家都只有一个脑袋,在某一个时刻(可以理解成非常小的一段时间),你肯定只能想一件事情,不可能同时想两件事情吧,所谓的三心二意就可以理解成java里面的多线程,你想两件事情说明你大脑开了两个线程(两个想法),,你能够三心二意就是因为,你可以想一会儿这件事然后再想想其他的事情,然后在某一个时刻你自己又迅速的转换思维切换到另一件事情上,你如果想完了一件事情,那么你可以集中精力想一件事情,java中的多线程也就是这个意思,在某一个时刻CPU只能处理一件事情,只要处理的线程只有一个了,那么剩下的哪个任务就可以独占CPU使用,当然你如果有两个脑袋那结果肯定就更不一样了,那就绝对可以称得上你同一时刻可以想两件事情了,对应与多核CPU那么真正的就可以同时处理两件事情了。

因为多线程存在一个特性:随机性。

造成的原因:CPU在瞬间不断切换去处理各个线程而导致的。

可以理解成多个线程在抢cpu资源。

多线程是为了同步完成多项任务,不是为了提供运行效率,通过提高资源使用效率来提高系统的效率.

线程是在同一时间需要完成多项任务的时候实现的.

多线程状态图

多线程--买票

需求:简单的卖票程序。多个窗口同时买票。

创建线程的第二种方式:实现Runable接口

步骤:

1,定义类实现Runnable接口

2,覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。

3,通过Thread类建立线程对象。

4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

为什么要将Runnable接口的子类对象传递给Thread的构造函数。

 因为,自定义的run方法所属的对象是Runnable接口的子类对象。

 所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。

5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

实现方式和继承方式有什么区别呢?

实现方式好处:避免了单继承的局限性。

在定义线程时,建议使用实现方式。

两种方式区别:

继承Thread:线程代码存放Thread子类run方法中。

实现Runnable,线程代码存在接口的子类的run方法。

  1. class Ticket implements Runnable//extends Thread
  2. {
  3. private int tick = 100;
  4. public void run()
  5. {
  6. while(true)
  7. {
  8. if(tick>0)
  9. {
  10. System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
  11. }
  12. }
  13. }
  14. }
  15.  
  16. class TicketDemo
  17. {
  18. public static void main(String[] args)
  19. {
  20.  
  21. Ticket t = new Ticket();
  22.  
  23. Thread t1 = new Thread(t);//创建了一个线程;
  24. Thread t2 = new Thread(t);//创建了一个线程;
  25. Thread t3 = new Thread(t);//创建了一个线程;
  26. Thread t4 = new Thread(t);//创建了一个线程;
  27. t1.start();
  28. t2.start();
  29. t3.start();
  30. t4.start();
  31.  
  32. }
  33. }

通过分析,发现,打印出0,-1,-2等错票                 多线程的运行出现了安全问题。

问题的原因:

        当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,

        另一个线程参与进来执行。导致共享数据的错误。

解决办法:

  对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。

Java对于多线程的安全问题提供了专业的解决方式。就是同步代码块。

synchronized(对象)

{

 需要被同步的代码

}

对象如同锁。持有锁的线程可以在同步中执行。

没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

火车上的卫生间---经典。

同步的前提:

1,必须要有两个或者两个以上的线程。

2,必须是多个线程使用同一个锁。

必须保证同步中只能有一个线程在运行。

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源。

  1. class Ticket implements Runnable
  2. {
  3. private int tick = 1000;
  4. Object obj = new Object();
  5. public void run()
  6. {
  7. while(true)
  8. {
  9. synchronized(obj)
  10. {
  11. if(tick>0)
  12. {
  13. //try{Thread.sleep(10);}catch(Exception e){}
  14. System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
  15. }
  16. }
  17. }
  18. }
  19. }
  20.  
  21. class TicketDemo2
  22. {
  23. public static void main(String[] args)
  24. {
  25.  
  26. Ticket t = new Ticket();
  27.  
  28. Thread t1 = new Thread(t);
  29. Thread t2 = new Thread(t);
  30. Thread t3 = new Thread(t);
  31. Thread t4 = new Thread(t);
  32. t1.start();
  33. t2.start();
  34. t3.start();
  35. t4.start();
  36.  
  37. }
  38. }

同步函数的锁

同步函数用的是哪一个锁呢?

函数需要被对象调用。那么函数都有一个所属对象引用。就是this。所以同步函数使用的锁是this。

通过该程序进行验证。

使用两个线程来买票。

    一个线程在同步代码块中。

    一个线程在同步函数中。

代码如下:

  1. class Ticket implements Runnable
  2. {
  3. private int tick = 100;
  4. Object obj = new Object();
  5. boolean flag = true;
  6. public void run()
  7. {
  8. if(flag)
  9. {
  10. while(true)
  11. {
  12. synchronized(this)
  13. {
  14. if(tick>0)
  15. {
  16. try{Thread.sleep(10);}catch(Exception e){}
  17. System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
  18. }
  19. }
  20. }
  21. }
  22. else
  23. while(true)
  24. show();
  25. }
  26. public synchronized void show()//this
  27. {
  28. if(tick>0)
  29. {
  30. try{Thread.sleep(10);}catch(Exception e){}
  31. System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
  32. }
  33. }
  34. }
  35.  
  36. class ThisLockDemo
  37. {
  38. public static void main(String[] args)
  39. {
  40.  
  41. Ticket t = new Ticket();
  42.  
  43. Thread t1 = new Thread(t);
  44. Thread t2 = new Thread(t);
  45. t1.start();
  46. try{Thread.sleep(10);}catch(Exception e){}
  47. t.flag = false;
  48. t2.start();
  49.  
  50. // Thread t3 = new Thread(t);
  51. // Thread t4 = new Thread(t);
  52. // t3.start();
  53. // t4.start();
  54.  
  55. }
  56. }

如果同步函数被静态修饰后,使用的锁是什么呢?

通过验证,发现不在是this。因为静态方法中也不可以定义this。

静态进内存是,内存中没有本类对象,但是一定有该类对应的字节码文件对象。类名.class  该对象的类型是Class

静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class

代码示例

  1. class Ticket implements Runnable
  2. {
  3. private static int tick = 100;
  4. //Object obj = new Object();
  5. boolean flag = true;
  6. public void run()
  7. {
  8. if(flag)
  9. {
  10. while(true)
  11. {
  12. synchronized(Ticket.class)
  13. {
  14. if(tick>0)
  15. {
  16. try{Thread.sleep(10);}catch(Exception e){}
  17. System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
  18. }
  19. }
  20. }
  21. }
  22. else
  23. while(true)
  24. show();
  25. }
  26. public static synchronized void show()
  27. {
  28. if(tick>0)
  29. {
  30. try{Thread.sleep(10);}catch(Exception e){}
  31. System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
  32. }
  33. }
  34. }
  35.  
  36. class StaticMethodDemo
  37. {
  38. public static void main(String[] args)
  39. {
  40.  
  41. Ticket t = new Ticket();
  42.  
  43. Thread t1 = new Thread(t);
  44. Thread t2 = new Thread(t);
  45. t1.start();
  46. try{Thread.sleep(10);}catch(Exception e){}
  47. t.flag = false;
  48. t2.start();
  49.  
  50. }
  51. }

死锁

同步中嵌套同步。

  1. class Test implements Runnable
  2. {
  3. private boolean flag;
  4. Test(boolean flag)
  5. {
  6. this.flag = flag;
  7. }
  8.  
  9. public void run()
  10. {
  11. if(flag)
  12. {
  13. while(true)
  14. {
  15. synchronized(MyLock.locka)
  16. {
  17. System.out.println(Thread.currentThread().getName()+"...if locka ");
  18. synchronized(MyLock.lockb)
  19. {
  20. System.out.println(Thread.currentThread().getName()+"..if lockb");
  21. }
  22. }
  23. }
  24. }
  25. else
  26. {
  27. while(true)
  28. {
  29. synchronized(MyLock.lockb)
  30. {
  31. System.out.println(Thread.currentThread().getName()+"..else lockb");
  32. synchronized(MyLock.locka)
  33. {
  34. System.out.println(Thread.currentThread().getName()+".....else locka");
  35. }
  36. }
  37. }
  38. }
  39. }
  40. }
  41.  
  42. class MyLock
  43. {
  44. static Object locka = new Object();
  45. static Object lockb = new Object();
  46. }
  47.  
  48. class DeadLockTest
  49. {
  50. public static void main(String[] args)
  51. {
  52. Thread t1 = new Thread(new Test(true));
  53. Thread t2 = new Thread(new Test(false));
  54. t1.start();
  55. t2.start();
  56. }
  57. }


Java面向对象 线程技术--上篇的更多相关文章

  1. Java面向对象 线程技术 -- 下篇

     Java面向对象 线程技术 -- 下篇 知识概要:              (1)线程间的通信           生产者 - 消费者 (2)生产者消费者案例优化 (3)守护线程 (4)停止线 ...

  2. Java——面向对象基础

    Java继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类具有父类的各种属性和方法,或子类从父类继承方法,使得子类具 ...

  3. Java面向对象(二、继承)

    Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法 ...

  4. java面向对象总结(二)

    Java 封装 实现Java封装的步骤 java面向对象值继承 概念: 继承的格式: 类和类之间的关系: 继承的特点: 继承的优缺点 继承的好处: 继承的缺点: 继承的注意事项: 使用继承的步骤: J ...

  5. Java学习笔记二十一:Java面向对象的三大特性之继承

    Java面向对象的三大特性之继承 一:继承的概念: 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方 ...

  6. Java面向对象重要关键字

    面向对象过程接触的重要关键字:extends   super   this   final   static  extends 关键字用作继承功能,可以申明一个类是从另外一个类继承而来的,一般形式如下 ...

  7. 夯实Java基础系列1:Java面向对象三大特性(基础篇)

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...

  8. java面向对象(封装,继承,多态,抽象,接口的定义和实现)

    1.封装 在面向对象程式设计方法中,封装(英语:Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定 ...

  9. Java面向对象OOP思想概述

    目录 OOP思想(Object Oriented Programming) 类和对象 接口 抽象类 OOP三大特性 封装 继承 多态 OOP复用的形式 OOP思想(Object Oriented Pr ...

随机推荐

  1. Day-8: 面对对象编程

    面对过程的程序设计方法意在将函数分成子函数,再依次调用这些函数来解决问题. 而面对对象的程序设计方法,来源于自然界,类是实例的抽象,实例是类的具体.自定义出来的对象是类,而所有的数据都可以看成是对象, ...

  2. 【C#多线程编程实战笔记】二、 线程同步

    使用Mutex类-互斥锁 owned为true,互斥锁的初始状态就是被主线程所获取,否则处于未获取状态 name为定义的互斥锁名称,在整个操作系统只有一个命名未CSharpThreadingCookb ...

  3. Flask05 cookie

    1 什么是cookie 就是网站存放到你浏览器中的一部分固定内容:当你下次访问我这个网站的时候,你会把之前我存放到你浏览器中的数据带回来给我        你要先登录(用户名.密码) ->   ...

  4. 201521123084 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  5. 201521123119《Java程序设计》第7周学习总结

    1. 本周学习总结 2. 书面作业 Q1.ArrayList代码分析 Q1.1 解释ArrayList的contains源代码 这段代码的主要目的是判断在对ArrayList遍历时所用的方法,在输入参 ...

  6. 201521123042 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 Q1.clone方法 1.1 Object ...

  7. 201521123063 java第一周总结

    20152112306 <Java程序设计>第一周学习总结 1.本周学习总结(2.20-2.26) java语言的特点: (1)简约且简单 (2)平台无关性 (3)面向对象 (4)多线程. ...

  8. 201521123052《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...

  9. java课程设计---彩票销售管理系统

    彩票购买销售系统 1.项目git地址 https://git.oschina.net/fenm/lotterry.git 部分项目地址提交截图 项目主要功能图 团队博客链接 http://www.cn ...

  10. python日记_01 python实现6个人围成一圈,扔到第三个人出局,循环扔的问题。

    #!/usr/bin/python shoplist=['mango','apple','carrot','banana','oracle','python'] length = len(shopli ...