黑马程序员——基础知识——线程间的通信

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

Day25

25.01 单例设计模式

       单例(单个实例即单个对象)设计模式:保证类在内存中只有一个对象

       如果保证类在内存中只有一个对象呢?

1、控制类的创建,不让其他类来创建本类的对象。Private

2、在本类中定义一个本类的对象。Singleton s

3、提供公共的访问方式 public static SingletongetInstance(){return s}

单例写法两种:

1、饿汉式 开发用这种方式


2、懒汉式 面试写这种方式。多线程的问题


25.02 Runtime类

       单例设计模式的应用场景:

              Runtime类是一个单例类,私有构造方法,对外提供访问Runtime方法。属于lang包下。可以执行DOS命令

25.03 Timer

       Timer类:计时器

       一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。

       TimerTask Date


25.03 Timer

       Timer类:计时器

       一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。

       TimerTask Date


25.04 两个线程间的通信

       1、什么时候需要通信

              多个线程并发执行时,在默认情况下CPU是随机切换线程的

              如果我们希望他们有规律的执行,就可以使用通信,例如每隔线程执行一次打印

       2、怎么通信

              如果希望线程等待,就调用wait

              如果希望唤醒等待的线程,就调用notify

              这两个方法必须在同步代码中执行,并且使用同步锁对象来调用

              wait和notify都是Object的方法



25.05 三个或三个以上间的线程通信

       多个线程通信的问题

              notify()方法是随机唤醒一个线程

              notifyAll()方法是唤醒所有线程

              JDK1.5之前无法唤醒指定的一个线程

              如果多个线程之间通信,需要使用notifyAll通知所有线程,用while来反复判断条件

下面是1.5版本之前的做法



线程间的通信注意的问题:

1、在同步代码块中用哪个对象调用锁,就用哪个对象调用wait和notify等方法;

2、为什么wait和notify方法定义在Object类中?因为锁对象可以是任意对象,而Object是所有类的基类(超类),所以wait和notify需要定义在Object这个类中

3、sleep和wait方法的区别?

区别1:首先sleep方法必须传入参数,即时间值,时间到了自动醒来。而wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入就是直接进入等待状态。

区别2:sleep方法在同步函数或同步代码块中,不释放锁,即睡着了也抱着锁睡,在指定时间可以自己醒来。wait方法在同步函数或者同步代码块中释放锁,因为如果不释放锁(即释放执行权),所有线程都在等着。

 

 

 

25.06 JDK1.5的新特性互斥锁

       1、同步 效率会比1.5版本之前的好一些

              使用ReentrantLock类的lock和unlock方法进行同步。替代synchronized

       2、通信

              Condition是一个接口,里面的await和signal替代了wait和notify

              使用ReentrantLock类的newCondition方法可以获取Condition对象

              需要等待的时候使用Condition的await方法, 唤醒的时候用signal方法

              不同的线程使用不同的Condition,这样就能区分唤醒的时候找那个线程




25.07 线程组的概述和使用

       1、线程组概述

              Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制

              默认情况下,所有的线程都属于主线程组

       public final ThreadGroupgetThreadGroup()//通过线程对象获取它所属的组

       public final StringgetName()//通过线程组对象获取它组的名字

              我们也可以给线程设置分组

1、ThreadGroup(Stringname)创建线程组对象并给其赋值名字

2、创建线程对象

3、Thrad(ThreadGroup?group,Runnable?targer,String? name)

4、设置整组的优先级或者守护线程

2、案例演示

       线程组的使用,默认是主线程组



25.08 线程的五种状态

       

5.09 线程池的概述和使用

       1、线程池的概述

              程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存周期很短的线程时,更应该考虑使用线程池。线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。在JDK5之前,我们必须手动实现自己的线程池,从5开始,Java内置支持线程池。

       2、内置线程池的使用概述

       JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法

              public static ExecutorService newFixedThreadPool(int nThreads)

              public staticExecutorService newSingleThreadExecutor()

              这些方法的返回值是ExecutorService对象,该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的线程。ExecutorService提供了如下方法

              Future<?>submit(Runnable task)

              <T>Future<T> submit(Callable<T> task)

       使用步骤:

              创建线程池对象

              创建Runnable实例

              提交Runnable实例

              关闭线程池

       3、案例演示

              提交的是Runnable


25.10 多线程程序实现的第三种方式(了解)

       提交的Callable

       Callable是一个接口


25.11 设计模式(简单工厂模式概述和使用)

       1、简单工厂模式概述

       又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例

       2、优点

              客户端不需要再负责对象的创建,从而明确了各个类的职责

       3、缺点

              这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护

       4、案例演示

              动物抽象类:public abstract Animal{public abstract void eat();}

              具体狗类:public class Dog extendsAnimal() {}

              具体狗类:public class Cat extendsAnimal() {}

              开始,在测试类中每个具体的内容自己创建对象,但是,创建对象的工作如果比较麻烦,就需要有人专门做这个事情,所有就知道了一个专门的类来创建对象。



25.12 工厂方法模式的概述和使用

       1、工厂方法模式概述

              工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现

              就是创建针对的对象,有其针对的工厂

       2、优点

              客户端不需要再负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性

       3、缺点

              需要额外的编写代码,增加了工作量

       4、案例演示


5.13 GUI如何创建一个窗口并显示

       1、Graphical User Interface(图形用户接口)


25.14 GUI布局管理器

       FlowLayout流式布局管理器

              从左到右的顺序排列

              Panel默认的布局管理器

       BorderLayout边界布局管理器

              东南西北中

              Frame默认的布局管理器

       GridLayout卡片布局管理器

              选项卡

       GridBagLayout网格包布局管理器

              非规则的矩阵


25.15 窗体监听


25.16 鼠标监听


25.17 键盘监听和键盘事件


       监听事件:满足某种条件就去执行某种方法

 

25.18 动作监听

       ActionListener就一个方法,就不需要Adapter适配器了,直接new对象就可以重写方法就可以了

此处的动作监听默认对的是鼠标左键和空格键,只要这两个动作都可以执行其中的方法


25.19 设计模式(适配器设计模式)

       1、什么是适配器

              在使用监听器的时候,需要定义一个类事件监听器接口

              通常接口中有多个方法,而程序中不一定所有的都用得到,但又必须重写,这很繁琐。

              适配器简化了这些操作,我们定义监听器时只要继承适配器,然后重写需要的方法即可。

       2、适配器原理

              适配器就是一个抽象类,实现了监听器接口,所有抽象方法都重写了,但方法内全都是空的

              适配器类需要定义成抽象的,因为创建该类对象,调用空方法是没有意义的,所以就不让创建适配器对象

              目的就是为了简化程序员的操作,定义监听器时继承适配器,只重写需要的方法就可以了


25.20 GUI需要知道的

       事件处理:

              事件:用户的一个操作:点鼠标,敲键盘等

              事件源:被操作的组件:按钮等就是事件源

              监听器:一个自定义类的对象,实现了监听器接口,包含事件处理方法,把监听源添加在事件源上,当事件发生的时候虚拟机就会自动调用监听器中的事件处理方法。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值