包(包概述、包与包之间访问、包导入import、Jar包)
概述
对类文件进行分类管理。就体现在文件夹上,写在程序文件的第一行。
类名的全称:包名.类名。包其实就相当于文件夹。
包也是一种封装形式。
包名所有字母都小写。
Package mypack;
Class PackageDemo
{
Public static void main(String[] args)
{
Sop(“Hello Package!”);
}
}
需要javac PackageDemo.java
Java mypack.PackageDemo 这样还是不能编译通过,需要把那个对应的.class文件存到对应的包文件夹里面去。不需要进到文件夹里面去运行,直接在外面运行就行,因为他们是一个整体。
但是每次都这样手动去创建吗?肯定不会这么麻烦的,那么如何解决呢?
在控制台中Javac回车后,可以找到javac -d .(当前目录)PackageDemo.java
Java mypack.PackageDemo就可以了。
包与包之间的访问
类名书写要带上包名了,否则编译不通过。若一个包中访问了另外一个包,而且另外一个包存放在另外一个路径下,也会编译错误。可以把包所在的位置配置在classpath下。Set classpath
有了包的概念,在包里面的类如果没有加public,外部的包都无法访问的。而且被访问的包的类的方法也必须是public的。
Protected 这种权限只有不同的包之间的子类才可以使用。只有你继承了我才可以用。跟我有关系的子类才可以用。
4种权限:
Public |
protected |
默认(什么关键字都没有写) |
private |
|
同一类中 |
||||
同一包中 |
不行 |
|||
子类中 |
不行 |
不行 |
||
不同包中 |
不行 |
不行 |
不行 |
包-导入(导入指定包中的类)
Import packa.DemoA;//导入了packa包中的DemoA类,并不导入包中的包。Import packa.abc.* 而不能直接这样写import packa.*
导入包的原则:用到哪个类就导入哪个类,如果想省事,就可以考虑使用通配符。高级编辑器不用自己写,可以自己解决。(自动生成)
一个.java文件只能有一个包。
Import干嘛用的呢? 为了简化类名书写而已。
Jar包
Jar:java的压缩包。(并不是图形化的工具,而是一个dos的工具。)
用法:命令行中jar后回车,用法全部出来了。(涉及目录的一些东西,需要温习)
多线程
1.概述
进程:(正在进行中的程序)用于开辟空间
线程:负责进程内容执行的控制单元。
一个进程中不可能没有线程,最少有一个线程。 一个进程中可以有多个执行路径,就叫做多线程。多搞一个线程,是为了执行另外一部分代码。
开启多个线程是为了同时运行多部分代码,每一个线程都有自己运行的内容。这个内容可以称为线程要执行的任务。
2.多线程的利与弊
CPU的切换是随机的,想要效果好,多核cpu解决效果才好。
好处:解决了多部分同时运行的问题。
弊端: 线程太多会导致效率的降低。
3. JVM中的多线程解析
有一点可以明确,虚拟机中肯定有一条线程在对主函数的代码在执行。而且堆中的垃圾回收也有一个线程用于垃圾回收(主函数中的线程不能用于去回收垃圾)。(最少都有2个线程,实际JVM有很多线程。)主线程(该线程的代码均定义在main中)、垃圾回收线程(定义在垃圾回收器中:由底层内部完成)。
演示了下子类重写Finalize方法(如果需要新功能,子类可重写finalize方法),如果不重写,直接清除垃圾即可。
首先gc()方法是垃圾回收(API文档),下面是示例,感受下多线程是怎么回事。
打印helloworld和demo ok 是2个线程在运行。也有可能demo ok先打印,还有可能只有一个demo ok打印(如果JVM已经结束了,那么demo ok就可能出现1次,或者0次,或者2次)误区:主线程结束了不代表虚拟机结束,垃圾回收线程并没有结束。
4. 主线程运行示例
Class Demo
{
private String name;
Demo(String name)
{
This.name=name;
}
Pulic void show()
{
For(int x=0;x<10;x++)
{
Sop(name+”...x=”x);
}
}
}
Class ThreadDemo2
{
Public static void main(String[] args)
{
Demo d1=new Demo(“旺财”);
Demo d2=new Demo(“xiaoqiang”);
D1.show();
D2.show();
}
}
以上是常规方式,不涉及多线程。
5. 多线程创建的方式—继承Thread类
线程是谁创建的呢?(由所在的操作系统创建完成的,我们无法直接使用系统来完成创建,看java中是否提供了解决该问题的对象,特别是有操作系统。所以先去找对象)
虚拟机一启动就有多线程。
如何创建一个线程?(目的是为了开启一条执行路径,去运行指定的代码和其他代码同时运行,而运行指定的代码就是这个执行路径的任务。JVM创建的主线程的任务都在主函数中,而自定义的线程它的任务在哪儿呢?)
Thread类用于描述线程,线程是需要任务的。所以Thread类也对任务的描述。这个任务就通过Thread类中的run()来体现。也即是,Run方法就是封装封装自定义线程运行任务的函数。(有点罗嗦,还是来一串代码比较直观)
Run方法中定义就是线程要运行的任务代码。
步骤:
1. 定义一个类继承thread类。
2. 覆盖thread类中的run()。
3. 直接创建Thread子类对象线程对象
4. 调用start方法并调用线程的任务run方法执行。
Class Demo extends Thread
{
private String name;
Class Demo extends Thread
{
This.name=name;
}
Public void run()
{
Show();
}
Pulic void show()
{
For(int x=0;x<10;x++)
{
Sop(name+”...x=”x);
}
}
}
Class ThreadDemo2
{
Public static void main(String[] args)
{
Demo d1=new Demo(“旺财”);//创建了一个线程
Demo d2=new Demo(“xiaoqiang”);//创建了另外一个线程
D1.show();//将其改为d1.start()就可以了;
D2.show();//改为d2.start();
}
}
但是郁闷的是,结果还是跟之前一样,没有改进啊?(原因在哪呢?)
测试下,在2条show语句中加一条打印haha的语句,结果依旧如此。说明目前只有主线程在执行。
思考:调用run和调用start方法有什么区别呢?
6.Thread类中的中的方法&线程名称
可以通过getname()获取线程名称:Thread-编号(从0开始)
当你创建了线程的时候,其实线程的名称就已经被定义好了。
Getname是获取对象的名称,要想获取运行的线程名称,要先拿到运行的对象。线程的方法中有一个:Thread.currentThread().getname();(currentThread()是当前对象,而getname()是它的名字)
主线程的名字就是main.
学习java还是要学会看API,自己学习。视频只能入门。
7.多线程运行图解
主线程出栈了,其他线程还在执行。
原因:三个线程里面各自有各自的栈区,弹栈压栈。相互之间一点都不冲突。
Sop(4/0);//throw new ArithmeticException
每一个线程都有可能出现异常,谁发生问题谁就先结束线程,而其余线程不受影响。