异常处理:
Try{}
Catch(Exception e){
}Finally{
Cleanup();//fianlly处理完异常要后做的事,可以不用。如果用了。则异常处理完后一定会执行;不管有没有异常。都会执行;不管是不是有return;有return则finally在return前先执行;
try{
*
return;}
catch{
*
}
finally{
*
}
print();//没错时finally里也有执行。但这句print没有执行;
}
如果return在catch中的话。则finally块则先执行;
异常的时候会强行中断;
Throwable底下的Error 与 exception 相同点和区别:
Runtiomexception
ArithmeticException
Print(“发生异常”+e.tostring());
e.printStackTrace();显示详细异常、getmessage也是显示错误异常。异常信息么printStackTrace();详细
public static void main(String[] args) {
ExceprionRaised obj=new ExceprionRaised();
try {
int result=obj.calculate(9,2);
System.err.println(result);
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
// TODO: handle exception
}
finally{
System.out.println("继续输出这");
}
class ExceprionRaised{
public void ExceptionRaised(){}
public int calculate(int operand1,int operand2){
int result=operand1/operand2;
return result;
}
}
多重catch。只能从子类开始——》父类。不能直接execption用这个父类放第一个catch。否则后面的catch不执行;
Throws于try
Throws直接监视方法和try工作位置不同;
1、 范围不同,throws直接放方法头,try放方法内;
2、 执行是throws的方法遇到异常会终止不再执行以下代码tyr-catch会再catch中做完处理后继续执行以下语句;
public static void main(String[] args) throws NullPointerException,Exception{//抛出异常多个异常。且整个main都被监测到。
int a[]=new int[10];
a[-1]=0;
System.out.println("aa");//则。aa不会被输出;
}
Main{
Try{
int a[]=new int[10];
a[-1]=0;
}
Catch{ }
System.out.println("aa");//可以输出
}
Throw只执行中断。其他的都不执行。(啥事都不干,丫的,一点用都么有。只有中断作用);
If(num2==0){ Throw new ArithmeticException();
}//若num2==0这抛出异常。直接停
Error和execption的区别:Error(错误)表示系统级的错误和程序不必处理的异常,是java运行环境中的内部错误或者硬件问题,比如,内存资源不足等,对于这种错误,程序基本无能为力,除了退出运行外别无选择。 Exception(违例)表示需要捕捉或者需要程序进行处理的异常,它处理的是因为程序设计的瑕疵而引起的问题或者在外的输入等引起的一般性问题,是程序必须处理的。
用户自定义异常
1. 创建一个继承于Throwable或其子类;
2. 添加构造方法
3. 在一个方法中使用throw抛出异常
4. 在另一个方法中捕获并处理异常;
进程,线程;
进程:正在执行的程序;就起个包装作用;
线程:进程执行的一条线索或路径;进程的小弟;真正干活的孩子,进程中至少有一个线程;
多线程:一个进程中的多个线程;
线程的开始:当要运行一个程序时,jvm首先会找到main函数,然后从main函数开始执行(也就是说,程序时从main函数开始运行)
此时,程序就成为一个进程,既然是进程肯定有线程的存在。此时的线程就是主线程。
线程的基本概念:
*线程的创建和启动:
线程的调度和优先级:10个等级
*线程的状态控制:
线程的同步:
1. *线程的创建和启动:
一、定义线程类实现runnable接口;
创建一个线程类,实现runnable接口;
重写run方法(run方法中的内容是线程运行的实体)
创建次线程类的对象
通过线程类的对象来创建线程。(thread类)
最后调用start方法使线程处于就绪状态
Public class xiancheng implements runnable{
Public void run(){
For(int I=1;i<=100;i++){
System.out.println(“runable1”+i);
}
}
}
Public class text2{
Main throws interruptedException{
Runnable xx=new xiancheng();
Thread ti=new thread(xx);
Ti.start();
For(){
Print(“xiancheng”+i)}
}
}//会出现线程抢占。也就是不是xiancheng1 到xiancheng100连着输出,中间可能会有runalbii
二、继承Thread类
创建线程类继承自thread
重写run方法
创建线程类的对象
调用此对象的start方法,使线程处于就绪状态
Class xianc extends Thread{
Public void run(){
For(int I i<=100)
Sysytemo.out.print(math.exp(i));
}
}
Main{
Thread ti=new xianc(0;
Ti.start();
For(){输出1到100}
}
Thread.currentThread().getName()
创建,start 就绪,调度(系统调度),运行状态若结束就终止,若导致阻塞的事件,阻塞状态,阻塞解除就绪状态,运行状态终止
Thread.sleep(): 线程暂停;
线程的方法:
Yield join sleep 的区别:
1.sleep()
使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是如果有Synchronized同步块,其他线程仍然不同访问共享数据。注意该方法要捕获异常
比 如有两个线程同时执行(没有Synchronized),一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有 Sleep()方法,只有高优先级的线程执行完成后,低优先级的线程才能执行;但当高优先级的线程sleep(5000)后,低优先级就有机会执行了。
总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。
2.join()
join()方法使调用该方法的线程在此之前执行完毕,也就是等待调用该方法的线程执行完毕后再往下继续执行。注意该方法也要捕获异常。
3.yield()
它与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。
4.wait()和notify()、notifyAll()
这 三个方法用于协调多个线程对共享数据的存取,所以必须在Synchronized语句块内使用这三个方法。前面说过Synchronized这个关键字用 于保护共享数据,阻止其他线程对共享数据的存取。但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出Synchronized数据块时让其他线 程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。
wait()方法使当前线程暂停执行并释放对象锁标志,让其他线程可以进入Synchronized数据块,当前线程被放入对象等待池中。当调用 notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有
锁标志等待池中的线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。
notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。
注意 这三个方法都是java.lang.Ojbect的方法!
1.run()和start()
这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由Java的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void。
2.关键字Synchronized
这个关键字用于保护共享数据,当然前提是要分清哪些数据是共享数据。每个对象都有一个锁标志,当一个线程访问该对象时,被Synchronized修饰的数据将被“上锁”,阻止其他线程访问。当前线程访问完这部分数据后释放锁标志,其他线程就可以访问了。
public ThreadTest implements Runnable
{
public synchronized void run(){
for(int i=0;i<10;i++)
{
System.out.println(" " + i);
}
}
public static void main(String[] args)
{
Runnable r1 = new ThreadTest();
Runnable r2 = new ThreadTest();
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
以上这段程序中的 i 变量并不是共享数据,也就是这里的Synchronized关键字并未起作用。因为t1,t2两个线程是两个对象(r1,r2)的线程。不同的对象其数据是不同的,所以r1和r2两个对象的i变量是并不是共享数据。
当把代码改成如下:Synchronized关键字才会起作用
Runnable r = new ThreadTest();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
---------------
JAVA线程的四种状态
线程有四种状态,任何一个线程肯定处于这四种状态中的一种:
1) 产生(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。
2) 可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正 处于线程池中等待排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一 定正在执行中。
3) 死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。
4) 停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执 行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状 态。
Public class text2 extends Thread{
Publi9c void run(){
Try{
Sleep(1000);//因为继承了Thread所以可以直接用。因为sleep在Thread中是static的。所以可以直接用
}
Catch(interruptedexception e){
e.printstacktrace();
}
}}
Main(string args){
Test2 t1=new test2();
T1.start;
}
Join:调用某线程的该方法。将当前线程有该线程“合并”,即等待该线程结束,当前线程进入就绪队列等待调度。(就是join先执行;)
Public class testjoin extends Thread{
Public void run(){
For(I<10){
Print(“I am testjoin”);
Try{
Sleep(1000);
}
catch(interruptedException e){
}
}
}
}
Main(){
Testjoin testjoin=new testjoin();
Testjoin.start();
Testjoin.join();//强行执行testjoin。不会把时间片给主线程;
For(int i;i<10;i++)
}
Thread.currentThread().getName();//获取当前进程名;
Yield(),让出cpu,但是别的线程能不能得到时间片————不一定。也就是说时间片让出,但是不一定其他的线程能得到;
线程的优先级设置:
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所以线程。线程调度器按照线程的优先级决定应调度哪个线程来执行;
线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5.(默认的)
Thread.min_prlority=1
Thread.MAX_PRIORITY=10
Thread.NORM_PRIORITY=5
使用下述方法获得或设置线程对象的优先级。
Int getPriority();
Void setPRiority(thread.norm_priority+4);//设置优先级为9
Class runable implements runnable{
Public void run(){
}
}
Main{
Runnable r=new runnable();
Thread t1=new thread(r);
Thread t2=new thread(r);
T1.start;
T2.start;
//创两个线程。不用创两个类。直接创一个类;
//Run方法只有一个。比用Thread子类少了许多个run方法。因为多一个线程则就多一个thread的子类。而用这种方法则直接一个run方法就够了;
}
线程同步:——上锁;
线程中不能有多个线程同时在两句代码之间执行,这就是线程同步。为了确保在任何时间点一个共享的资源只能被一个线程使用,就需要使用”同步”。
实现同步的方法有两种:
同步代码块:
Synchronized(object//要同步的对象一般都是当前线程;){
//要同步的语句;
}
***同步方法:
Synchronized void method(){
//要同步的语句
//synchronized一定要放在返回类型前面;
}
class nclass2{
int num=0;
public synchronized void add() throws Exception{
num++;
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+":"+num);
}
}
class test6 implements Runnable{//问什么用runnable——要保证是同一个run。
nclass2 t6=new nclass2();
public void run(){
try {
t6.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException{
test6 r=new test6();
Thread t1=new Thread(r);
t1.start();
Thread t2=new Thread(r);
t2.start();
}
输出的是1 2;
如果少了synchronized则。输出的是不定的
死锁:线程1占领o1资源抢o2资源,线程2占领o2抢o1资源:
class testdeadlock implements Runnable {
public int flag = 1;
static Object o1 = new Object();
static Object o2 = new Object();
public void run() {
System.out.println("flag=" + flag);
if (flag == 1) {
synchronized (o1) {
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (o2) {
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("0");
}
}
}
}
}
public static void main(String[] args) throws InterruptedException{
testdeadlock tl=new testdeadlock();
testdeadlock t2=new testdeadlock();
tl.flag=1;
t2.flag=0;
Thread r1=new Thread(tl);
Thread r2=new Thread(t2);
r1.start();
r2.start();
}
总结:
1. 线程和进程的概念;
2. 线程创建的两过程——实现runnable接口,,继承Thread类,两种方式的不同:第一种方式创建的多个线程拥有唯一的线程实体,第二种方式创建的多线程具有不同的多个线程实体。
3. 线程的状态及其转换:创建——start——就绪——运行——结束,(就绪和运行中还有阻塞)
4. 使用了Thread里的一些方法:sleep。Static。join方法强取时间片. Yelid方法让出时间片。
5. 线程的同步:Synchronized死锁。
创建一个新文件:
file类
public static void main(String[] args) throws InterruptedException{
//String pathname=“D:\\ONCE\\hello.txt”;
//File f=new file(pathname);两句等同于一句。(下面面一句)
//String pathname=“D”+file.pathseparator+pile.separator+”ONCE\\hello.txt”;//等同于stringpathname……
File f=new File("D:\\ONCE\\hello.txt");//路径。双斜杠,转义字符。提供文件名及后缀名。
try {
f.createNewFile();//创建文件;
Thread.sleep(5000);//测试下面的删除
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//File f=new file(filename);
If(f.exists()){ //判断是否存在f文件
f.delete();//文件删除
}
public static void main(String[] args) throws InterruptedException{
File f=new File("D:\\ONCE\\hello.txt");
if(f.exists()){ //判断是否存在f文件
f.delete();//文件删除
}
}
f.mkdir();//创建文件夹//mkdirs 可以直接建没有上级文件夹的文件。如没有NOCE。在D:\\ONCE\\下建个hello文件夹。则可以直接用mkdirs