java多线程复习转载

来源:互联网 发布:c语言五子棋代码 编辑:程序博客网 时间:2024/05/20 06:25
1 .finally 语句:这个代码块中定义的是一定会执行的代码。
不能被catch块中的return语句结束,可是能被System.exit(0)结束。

2.主要用于关闭资源,只要使用了资源,就一定要将其关闭。

3.应用:数据库的连接,连接——操作——关闭。可能在操作过程中出现异常,没关闭数据库,就需要把关闭数据库放在finally语句里面。
2 组合方式:
try{}catch (){}、try{}catch(){}、try{}finally{}(这种用于关闭资源)

3 .异常在覆盖时的细节

1.子类在覆盖父类方法时,如果父类方法抛出了异常,子类覆盖的方法只能抛出父类方法异常或其子类。
2.父类方法如果抛出多个异常,子类在覆盖父类方法时,只能抛出父类异常的子集。
3.如果父类中的方法没有抛出异常,子类覆盖父类时,绝对不能声明异常。只能进行 try{} catch 处理;如果处理不了,那就应该让程序
停掉,让调用者知道。即在catch中抛出RuntimeException异常或其子类对象,这时不用抛,RuntimeException不用在函数上声明。
包(package):包名具有唯一性 在windows中的具体体现:文件夹。
包的作用:1.分类管理类文件;
2.对类提供了多层名称空间。
2.如何定义:使用关键字 package,定义必须定义在源代码的第一行,类名的全称是:包名.类名;
包名全小写如mypackage.
3.步骤:1.javac -d 包的路径 全类名.java
2.set classpath=包的路径;
3.java 包名.类名
一个包中不能存在两个public修饰的类。
被访问的包中,类和方法都需要被public修饰,否则权限不够。

4.包与包之间的继承
protected:包的修饰符,保护权限,只有子类才能用;用于保护父类中的成员。

四种权限: public protected default(默认的) private
同一个类中: ok ok ok ok
同一个包中: ok ok ok
子类: ok ok
不同包中: ok

5.简化书写:使用import关键字导入,格式:import 全类名;导入的都是包中的类;若是需要导入多个类,则使用通配符,如 import packa.*。而在真实开发时,用到哪个则导入哪个,根本也用不到导入,用高级编辑器。

6.注意:
1.import packa.* :只导入packa包的当前目录下的所有类,而不导入当前目录下的包。
2.当导入的包中的类有重名时,使用该类时,必须用包名.类名的全名称,否则无法区分,会产生使用的不确定性。
如 import packa.Demo;
import packb.Demo;
不能new Demo(),而需new packa.Demo();
5 Jar包:java的压缩包。
-c:创建新的归档文件
-x:解压
java压缩工具:jar cvf haha.jar pack
6 多线程技术
1.进程:正在进行中的程序。
2.线程(Thread):负责进程进行执行。一个进程至少有一个线程,若有多个则称为多线程程序;线程也可以称为执行线程、执行路径、执行背景。
3.好处:可以同时执行多个程序。

4.JVM多线程的基本体现:
JVM也是多线程,至少有一个主线程和垃圾回收线程。主线程执行的是主函数中的内容,垃圾回收线程执行的对堆内存进行内存释放的代码。
5.垃圾回收的方法:finalize(),垃圾回收
gc():运行垃圾回收器,System.gc();启动后不一定立即执行,因为CPU在随机做着切换,先切换到哪就先执行哪个。
6.自定义线程:通过APIThread类的查阅,两种方式:
1.继承Thread类,覆写run()方法,创建Thread子类对象,调用start方法来开启线程并调用run方法;线程类在描述线程时,有一个功能函数run,专门用于封装执行的任务

主线程也是同理,该线程执行的任务在主函数中。

Thread t=new Thread();创建进程。
1.覆写run方法的原因:创建进程的目的是为了运行指定的代码,任务就应该自己指定。

2.特定方法start():开启线程并调用run方法运行线程。

start和run区别:调用run方法,并没有开启新的线程,都是由主线程来执行,无法完成同时运行的需求;
调用start方法,开启了新的线程并调用了线程的任务方法run方法,实现了代码同时执行。

3.执行路径是在每一条路径上先进后出的,即每个线程都有自己单独的一片栈内存空间。
4.currentThread():返回当前正在执行的进程,Thread.currentThread().getName();结果是Thread-编号,编号从0开始。
5.线程是分区来进行管理的,当前线程发生异常只影响当前线程,不影响其它线程。
6.主线程是最后结束的线程,只要还有存活的线程,它就不能结束。
第二种:实现Runnable接口,见第十二天日志
创建线程的目的:为了开辟一个执行路径去执行指定的代码,让其和其它代码同时运行;意味着每一个线程的创建都有自己要运行的内容,而这个内容也称为线程的任务。
线程的四种状态:被创建、运行、冻结notify、sleep、wait、消亡(还有一个特殊状态:就绪)
被创建:start();
运行:具备执行资格,同时具备执行权
冻结:sleep(time), wait()---notify()唤醒;线程释放了执行权,同时释放资格。
临时阻塞状态:线程具备CPU的执行资格,没有CPU的执行权
消亡:stop()
 

创建线程的第一种方式是:
1,继承Thread,//** extends Thread
2,复写run方法,将线程要运行的任务代码存储到run方法中。//public void run(){}
3,创建Thread类的子类对象。Ticket t = new Ticket(); Thead t1 = new Thread()
4,调用start方法开启线程并调用run方法。t1.start()
创建线程的第二种


1,定义类实现Runnable接口
2. 覆盖该接口中的run()方法
3,通过Thread类创建线程对象,
4,将实现Runnable接口的实现类的对象作为参数传递给Thread类的构造函数
将run方法所属的对象传递给线程,让线程去运行指定的对象 的run 方法。
5,调用Thread类的start 方法开启线程
Runnable接口的好处:
避免了单继承的局限性
Runnable接口的出现 ,更是按照面向对象的思想,将线程要运行的任务进行单独的封装,
降低了线程对象和线程任务的耦合性。

class Demo extends Thread{//第一种
public viod run(){}
}
Demo d1 = new Demo();
Demo d2 = new Demo();//线程对象和线程的耦合性强
//将线程任务进行描述
class Demo implements Runnable{//第二种
public void run(){}
}
class Demo2 implements Runable{
public void run(){
}
}
Demo d = new Demo();//将线程任务封闭成对象
Demo2 d2 = new Demo2();
Thread t = new Thread(d2);//通过线程对象的构造函数和任务相关联
创建线程,建议使用第二种方式。
class Demo implements Runnable{
//将线程要运行的任务代码封装到了run方法中
public void run(){
for(int x=1; x<=20; x++){
System.out.println(Thread.currentThread().getName()+"..."+x);
}
}
}
class ThreadDemo4{
public static void main(String args[]){
Demo d=new Demo();
//创建线程对象。因为没有了Thread的子类 ,所以通过Thread类来完成线程对象的创建。
Thread t1=new Thread(d);
Thread t2=new Thread(d);
t1.start();//开启了线程并调用了线程中的run方法。只不过线程类中的run方法并没有定义我们要让线程运行的内容。
t2.start();
}
}
第一种方式
class Demo extends Thread{
//覆盖Thread类中的run方法,将线程任务代码封装到该方法中。
public void run(){
for(int x=1; x<=20; x++){
System.out.println(Thread.currentThread().getName()+"...extends..."+x;
}
}
}

创建线程,建议使用第二种方法
多线程的安全问题
对安全问题的分析:
1,多个线程在处理同一个共享数据
2, 线程任务代码中有多条语句在操作这个共享数据
3,这些多条操作共享数据的语句被多个线程分开进行执行
也就是说,在一个线程执行这些语句的过程中,其它线程参与了运算,导致数据的错误
总结: 线程任务代码中只要存在着:
1,共享数据
2 多条操作共享数据的语句
就容易产生多线程的安全问题

解决线程安全问题的原理:
将多条操作共享数据代码进行封装,
在某一时刻,只能一个线程在内运行,在运行期间,其它的线程都进不来
只有这个线程运行完,其它线程才有机会执行其中的内容
怎样封装呢?
JAVA中提供了一个用于封闭的代码块,就是同步代码块
synchronized(obj)//这个obj对象可以是任意的
{
}
synchronized synchronized//相当于一个锁 举例:火车上的卫生间
为了给同步代码块指定一个对象,可以用自定义的,也可以用已有的
如object

同步的好处:解决了多线程的安全问题
当程序中出现了多线程的安全问题时,加入了同步进行解决,却发现问题依旧,
你可以先明确一下同步的前提
同步的前提:
必须有多个线程,而且使用的是同一个锁。

同步的弊端:降低了效率。容易出现死锁

class Ticket implements Runnable{
private int num = 100;
private Object obj = new Object();
public void run(){
while(true){

synchronized(obj){
if (num>0)
try{Thread.sleep(10)}
catch(InterruptedException e){
e.getMessage()}//让线程在这里小睡一下
System.out.println(Thread.currentThread().getName()+"..."+num--);
}
}
}
}

class TicketDemo2{
public static void main(String args){
Ticket t = new Ticet();

Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);

t1.start();
t2.start();
t3.start();
t4.strt();
}
}
原创粉丝点击