黑马程序员-笔记-05-基础

来源:互联网 发布:淘宝卖家体验中心 编辑:程序博客网 时间:2024/06/06 19:25

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

java的匿名内部类:
    没有名字的内部类。就是内部类的简化形式。如果只在方法中只使用一次就可以使用匿名类。匿名内部类其实就是一个匿名子类对象想要定义匿名内 部类:需要前提,内部类必须继承一个类或者实现接口。形式:new 父类/父接口(){实现方法} 。

java的异常:Exception 
    java的 异常全部继承与Throwable接口,下属rror类与Exception两个子类
    java中的异常分为运行时异常(Runtime异常)和编译时异常。后者在编译过程中需要被抛出,或者使用try{}catch(Exception e){}来处理。
    当try块中抛出多个异常时,catch对应多个,那么父类的异常一定放在最后扑捉,否则编译错误。这也与异常的处理相矛盾。
    异常在继承中:一个子类重写父类的方法是,不能抛出比父类更多的异常,也不能抛出父类未抛出的异场。

    在一个方法中抛出异常使用throw new Exception(); 在方法上声明抛出则使用,throws  异常类名,异常类名...; 

 

java的多线程: Thread    
    java中实现多线程的两种方法:
    1.继承Thread类,复写run()方法,创建对象,调用start();方法。 
    2.实现Runnable接口,
复写run()方法,创建对象,将对象以参数形式传递给Thread的构造函数,调用Thread.start();方法。
示例代码: 

public class Play11 {public static void main(String[] args) {final Runnable r = new Runnable() {private Integer ticket = 100;@Overridepublic void run() {while (ticket > 0)// 锁的使用,有助于数据安全,不过降低了效率。每次判断锁。synchronized (this) {if (ticket > 0) {// 此处异常因为是复写父类,不能抛出,否则会报错。try {Thread.sleep(10);} catch (InterruptedException e) {}System.out.println(Thread.currentThread().getName()+ " " + ticket--);}}}};new Thread(r).start();//匿名内部类写法。 new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread());}}).start();}} 

多线程同时访问同一对象时带来的安全问题,当一条线程正在执行一个数据,另一条线程得到执行权,开始同时操作该数据,当前一个线程再次操作该数据时,该数据已经改变,可能带来安全问题。
解决多线程安全问题:同步代码块--synchronized(锁对象){需要一次执行完毕的动作}

 
synchronized使用在普通方法上,所持有的锁是this,使用在静态方法上时,使用的锁是该类的字节码。

synchronized使用不当会带来死锁。两条线程,a线程持有N锁需要使用M锁,b线程持有M锁,需要使用N锁,此时死锁。
 最简单的死锁:
public class Play12 {public static void main(String[] args) {Run1 r1 = new Run1();Run2 r2 = new Run2();new Thread(r1).start();new Thread(r2).start();}}class Run1 implements Runnable {int i = 1000;@Overridepublic void run() {while (i > 0)synchronized (Run1.class) {synchronized (Run2.class) {System.out.println(Thread.currentThread().getName() + " "+ i--);}

java多线程:wait()和sleep()的区别:
          两者都放弃cpu的执行权。前者会同时释放锁,后者则不会。前者需要使用唤醒,后者在一定时间后就会自动唤醒。

同步代码块的等待唤醒机制:wait(),notify();也就是线程间通信。
java5.0中对同步进行了升级,建议使用Lock对象代替java中的等待唤醒机制。
    java中的lock,可以起到同步代码块的所有功能,同时,具有更高的效率,通过使用Condition,可以唤醒需要的等待线程
   在同步代码完成后,必须释放锁。


    使用Lock来实现生产者消费者问题:

public class Play13 {/*** 生产者消费者。*/public static void main(String[] args) {Res res = new Res();new Thread(new Pro(res)).start();new Thread(new Cus(res)).start();new Thread(new Pro(res)).start();new Thread(new Cus(res)).start();new Thread(new Pro(res)).start();new Thread(new Cus(res)).start();}}class Res {private int i = 0;private boolean flag = false;Lock lock = new ReentrantLock();Condition con_p = lock.newCondition();Condition con_c = lock.newCondition();public  void pro() {//上锁 lock.lock();try {while (flag) {//设置条件等待con_p.await();}System.out.println(Thread.currentThread().getName() + " 生产  +++"+ ++i);//更换标识 flag = true;//根据锁设置额条件,唤醒消费者的锁。 con_c.signal();} catch (InterruptedException e) {} finally {//锁一定要被释放,所一定要被放在finally lock.unlock();}}public  void cus() {lock.lock();try {while (!flag) {con_c.await();}System.out.println(Thread.currentThread().getName() + " 消费  -----"+ i);flag = false;con_p.signal();} catch (InterruptedException e) {} finally {lock.unlock();}}}

线程的其他知识:
    线程的终止:stop方法,此方法已经过时,它会引起Interruption异常。
    多线程执行的就是run()方法,而其中多使用循环结构,控制循环结构结束,那么线程也就结束。

守护线程:
在线程启动前,使用setDaemon(true);方法,声明该线程为守护线程。
特点:
    1当正在运行的线程都是守护线程时,JVM退出。

    2该方法必须在启动线程前调用。

    3主线程是前台线程,前台线程一结束,守护线程自动结束。

线程的join方法: 

    当cpu执行到某个线程的join方法是,其他线程全部等待该线程完毕后在执行。其实该方法就是抢夺cpu执行权。

线程的优先级以及yield
   设置线程优先级 setPriority(int newPriority)默认是5(NORM_PRIORITY),该方法带来的优先效果并不明显。
    yield:临时停止。它的作用是稍微降低线程运行,是线程降低,已达到接近平均运行。一般不使用。

原创粉丝点击