java基础知识05


1.包 package          (包名的所有字母小写)

    1.对类文件进行分类管理

    2.给类提供多层命名空间

    3.写在程序文件的第一行

    4.类名的全称是:   包名.类名

    5.包也是一种封装形式

    总结:1.包与包之间进行访问,被访问的包中的类以及类中的成员,需要被public修饰

               2.不同包中的子类还可以直接访问父类中被protected权限修饰的成员

               3.包与包之间可以使用的权限只有两种,public和protected

                                       权限           public                protected             default                 private

                                 同一个类中         OK                         OK                    OK                          OK

                                 同一个包中          OK                           OK                   OK                             NO

                                 子类                     OK                             OK                       NO                        NO

                                  不同包中             OK                              NO                       NO                          NO

            为了简化类的书写,使用一个关键字 import

            import导入的是包中的类,建议不要写通配符*,需要用到包中的哪个类,就导入哪个类,建议定义包名不要重复,可以使用url来完成定义,因             为url是唯一的。

           例如:  package  cn.itcast.demo

          2.jar包

2.多线程

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

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

       一个进程中至少有一个线程

       jvm启动的时候会有一个进程 java.exe,该进程至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中,该线程称之为          为主线 程。

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

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

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

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

               

                    步骤:1.定义类继承Thread

                               2.重写Thread类中的run方法

                               3.调用线程的start方法(该方法两个作用:启动线程、调用run方法)

                    发现运行结果每次都不同,因为每个线程都获取cpu的执行权。cpu执行到谁,谁就运行。明确一点,在某一个时刻,只能有一个程序在运                     行(多核除外),cpu在做着快速的切换,已达到看上去是同时运行的效果。我们可以形象把多线程的运行行为看做在互相抢夺cpu的执行                     权,这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行多久,cpu说的算。

                     1.为什么要重写run方法呢? 

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

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

                     2.线程都有自己默认的名称。     Thread-编号,该编号从0开始

                        static  Thread    currentThread();        获取当前线程对象

                             getName();             获取线程名称

                                设置线程名称              setName()或者构造函数

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

                    

         2.创建线程的第二种方式:实现Runnable接口

               步骤:

                           1.定义类实现Runnable接口

                           2.重写Runnable接口中的run方法,将线程要运行的代码存放在该方法中

                           3.通过Thread类建立线程对象

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

                                为什么要将Runnable接口的子类对象传递给Thread的构造函数呢?因为自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去执行

                                指定对象的run方法,就必须明确该方法所属对象

                           5.调用Thred类的start方法,开启线程并条用Runnable接口子类的run方法

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

              实现方式好处:避免了单继承的局限性,在定义线程时,建议使用实现方式

              两种方式区别:

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

                        实现Runnable: 线程代码存放于接口的子类的run方法中

 4.多线程的安全问题

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

          问题的原因:当多条语句在操作同一个线程共享数据时,一条线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误

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

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

                            synchronized(对象)

                           {

                                        需要被同步的代码;

                           }

                          1.对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取cpu的执行权,也进不去。火车上的卫生间-----经典!!

                           2.同步的前提

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

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

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

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

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

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

                        如果同步函数被静态修饰后,使用的锁是什么呢?通过验证,发现不再是this,因为静态方法中也不可以定义this,静态进内存时,内存中没有本类

                        对象,但是一定有该类对应的字节码文件对象  类名. class, 该对象的类型是Class.静态的同步方法,使用的锁是该方法所在类的字节码文件对象类名.class

                        死锁:同步中嵌套同步

5.线程间通讯:其实就是多个线程在操作同一个资源,但是操作的动作不同。

                   等待唤醒机制: wait;         notify();         notifyAll();        

                   都使用在同步中,因为要对持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁。

                   为什么这些操作线程的方法要定义Object类中呢?因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁,只有同一                     个锁上的被等待线程,可以被同一个锁上notify 唤醒。不可以对不同锁上得线程进行唤醒。

                   也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法,定义Object类中。

                   1.stop方法已经过时,如何停止线程?只有一种,run方法结束。开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让                       run方法结束,也就是线程结束。

                       特殊情况:当线程处于了冻结状态,就不会读取到标记,那么线程就不会结束。

                                        当没有指定的方式让冻结的线程恢复到运行状态时,这是需要对冻结进行解除,强制让线程恢复到运行状态中来,这样就可                                           以操作标记让线程结束。Thread类提供该方法           interrupt();

                    2.join的特点:当A线程执行到了B线程的join方法时,A线程就会等待,等待B线程都执行完,A才会执行。join可以用来临时加入线程执行 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值