JAVASE学习笔记
生产者与消费者:
1 public class ProducerConsumer { 2 public static void main(String[] args) { 3 Basket bs=new Basket(); 4 Producer p=new Producer(bs); 5 Consumer stu1=new Consumer("张东",bs); 6 Consumer stu2=new Consumer("王强",bs); 7 Consumer stu3=new Consumer("赵璐",bs); 8 new Thread(p).start(); 9 new Thread(stu1).start(); 10 new Thread(stu2).start(); 11 new Thread(stu3).start(); 12 } 13 } 14 15 class ManTou { 16 int id; 17 ManTou(int id){ 18 this.id=id; 19 } 20 public String toString(){ 21 return "第"+id+"个馒头" ; 22 } 23 } 24 25 class Basket { 26 int index = 0; 27 ManTou[] mt = new ManTou[10]; 28 29 public synchronized void push(ManTou ton) { 30 while (index == mt.length) { 31 try { 32 this.wait(); 33 } catch (InterruptedException e) { 34 e.printStackTrace(); 35 } 36 } 37 this.notifyAll(); 38 mt[index] = ton; 39 index++; 40 } 41 public synchronized ManTou pop() { 42 while (index == 0) { 43 try { 44 this.wait(); 45 } catch (InterruptedException e) { 46 e.printStackTrace(); 47 } 48 } 49 this.notifyAll(); 50 index--; 51 return mt[index]; 52 } 53 54 } 55 56 class Producer implements Runnable{ 57 Basket bs= null; 58 Producer(Basket bs){ 59 this.bs=bs; 60 } 61 public void run(){ 62 for(int i=1;i<=15;i++){ 63 ManTou mt=new ManTou(i); 64 bs.push(mt); 65 System.out.println("李师傅生产了"+mt.toString()); 66 try{ 67 Thread.sleep((int)(Math.random()*100)); 68 }catch(InterruptedException e){ 69 e.printStackTrace(); 70 } 71 } 72 } 73 74 } 75 76 77 class Consumer implements Runnable{ 78 Basket bs= null; 79 String name; 80 Consumer(String stu,Basket bs){ 81 this.bs=bs; 82 name=stu; 83 } 84 public void run(){ 85 for(int i=1;i<=5;i++){ 86 ManTou mt=bs.pop(); 87 System.out.println(name+"消费了"+mt.toString()); 88 try{ 89 Thread.sleep((int)(Math.random()*1000)); 90 }catch(InterruptedException e){ 91 e.printStackTrace(); 92 } 93 } 94 } 95 96 }
java类的初始化顺序
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
子类main方法
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
上面所说有一点是错的,即静态不管是变量还是初始化块都会按顺序加载,别人的垃圾博客误人子弟啊!
1 public class Interview_02 extends X{ 2 Interview_02(){ 3 System.out.println("Z"); 4 } 5 Y y = new Y(); 6 7 public static void main(String[] args) { 8 9 new Interview_02(); 10 11 } 12 13 14 15 } 16 17 class X{ 18 Y b = new Y(); 19 X(){ 20 System.out.println("X"); 21 } 22 } 23 24 class Y{ 25 Y(){ 26 System.out.println("Y"); 27 } 28 }
执行结果为:YXYZ
assertEquals
函数原型1:assertEquals([String message],expected,actual)
参数说明:
message是个可选的消息,假如提供,将会在发生错误时报告这个消息。
expected是期望值,通常都是用户指定的内容。
actual是被测试的代码返回的实际值。
函数原型2:assertEquals([String message],expected,actual,tolerance)
参数说明:
message是个可选的消息,假如提供,将会在发生错误时报告这个消息。
expected是期望值,通常都是用户指定的内容。
actual是被测试的代码返回的实际值。
tolerance是误差参数,参加比较的两个浮点数在这个误差之内则会被认为是
相等的。
抽象类:
(1)凡是用abstract 修饰符修饰的类被称为抽象类。凡是用abstract修饰符修饰的成员方法被称为抽象方法。
(2)抽象类中可以有零个或多个抽象方法,也可以包含非抽象的方法。
(3)抽象类中可以没有抽象方法,但是,有抽象方法的类必须是抽象类。
(4)对于抽象方法来说,在抽象类中只指定其方法名及其类型,而不书写其实现代码。
(5)抽象类可以派生子类,在抽象类派生的子类中必须实现抽象类中定义的所有抽象方法。
(6)抽象类不能创建对象,创建对象的工作由抽象类派生的子类来实现。
(7)如果父类中已有同名的abstract方法,则子类中就不能再有同名的抽象方法。
(8)abstract不能与final并列修饰同一个类。
(9)abstract 不能与private、static、final或native并列修饰同一个方法。
(10)在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
(11)抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。抽象类必须被继承,才能被使用。(它没有足够信息描绘一个对象,只有等子类来继承完善后才能使用)
接口:(抽象方法的集合)
(1)类描述对象的属性和方法。接口则包含类要实现的方法。
(2)除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
(3)接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法(所有方法都是抽象的方法),否则就必须声明为抽象类。
(4)接口没有构造方法,支持多重继承,不能包含成员变量,除了static和final变量,如果不写修饰符,默认就是static final;
(5)接口是隐式抽象的,当声明一个接口和接口中方法的时候,不必使用abstract关键字。接口中的方法都是公有的。
(6)类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类 中抛出该强制性异常。
区别
接口不是类,抽象类是一个功能不齐全的类,都不能实例化对象。
一个类可以实现(implements)多个接口。一个类只能继承(extends)一个抽象类。
接口没有构造函数,所有方法都是 public abstract的,一般不定义成员变量。(所有的成员变量都是 static final ,而且必须显示初始化)。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
一个实现接口的类,必须实现接口内所描述的所有方法(所有方法都是抽象的方法),否则就必须声明为抽象类。
如果一个类包含抽象方法,那么该类必须是抽象类。任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
内部类:
虽然我们在定义的内部类的构造器是无参构造器,编译器还是会默认添加一个参数,该参数的类型为指向外部类对象的一个引用,
所以成员内部类中的Outter this&0 指针便指向了外部类对象,因此可以在成员内部类中随意访问外部类的成员。
从这里也间接说明了成员内部类是依赖于外部类的,如果没有创建外部类的对象,
则无法对Outter this&0引用进行初始化赋值,也就无法创建成员内部类的对象了。
-----------------------详情参照博客 https://www.cnblogs.com/dolphin0520/p/3811445.html
private static ExecutorService executor = new ThreadPoolExecutor(100, 1000, 0L,
TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10000),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());
ForkJoin框架是从jdk7中新特性,它同ThreadPoolExecutor一样,也实现了Executor和ExecutorService接口。
它使用了一个无限队列来保存需要执行的任务,而线程的数量则是通过构造函数传入,
如果没有向构造函数中传入希望的线程数量,那么当前计算机可用的CPU数量会被设置为线程数量作为默认值。
帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行。而在这时它们会访问同一个队列,
所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,
被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。
java提供队列方法大全:
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列已满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞