标签:cbo ESS 休眠 苹果 reac jdk1.5 日期格式 构造方法 err
Date对象
Date类的方法
·构造方法:
-public Date()
-public Date(Long date)传递一个long类型的参数
·获取时间:
-public long getTime()以long类型返回
long cur=System.currentTimeMillis();//获取从1970年1月1日到当前的毫秒数
日期格式化对象(SimpleDateFormat)
·构造方法:
-public SimpleDateFormat(String pattern)//参数是我们需要的格式"YYYY-MM-DD HH:mm:ss.SSS"
·格式转换:
-public final String format(Date date)//将Date类型转变成String类型日期
-public Date parse(String sourse)//将String类型日期转变成Date类型
sdf.setLenient(false);//开启严格模式
泛型
泛型<T>通配符?有两个子通配符分别是?extends类,?super类
?extends类:可以用于类的泛型,也可以用于方法的泛型;是设置范型的上限,一旦为类设置范型上限,那么实例化
子类的时候只能是泛型上限所对应的类或者子类 fun(Message<?extends Object> msg);
?super 类:只能用于方法参数的泛型,能接受的参数的泛型只能是该类或者该类的父类 fun(Message<?super integer> msg);
新泛型
如果要定义一个方法可以接受任意个数的参数,这里就可以用新泛型来实现public static <T>T[] fun(T...temp)
{return temp;}
异常
Eorr和Exception都是Throwable的子类
Eorr:是程序还没有运行之前就出现的错误,是JVM出现的错误是不能通过捕获处理的
Exception:是程序在运行中出现的异常,是可以通过捕获处理的。
程序出现了异常JVM会自动实例化一个对应的异常对象,再判断是否存在异常的捕获语句 throws关键字放到方法名后面,一旦方法中使 用了关键字,那么在该方法中出现的异常,将会向上抛出,交给调用处去处理该异常。
throw关键字位置是在方法体中,手动抛出异常。
Exception是异常要求强制处理的,RuntimeException不要求强制性处理,可以选择性的处理
断言
assert关键字是在jdk1.4版本引入的表示断言
assert num==20; (num的值是20)
线程与进程
进程是线程的载体,一个进程由多个线程组成,线程要依附于线程,一旦进程关闭,那么线程就不存在了。
系统要区分线程是通过线程的名字来区分的,那么如何设置和获取线程的名字呢?
-public final String getName()获取线程的名字
-public final void setName(String name)设置线程的名字
-public Thread(Runnable target,String name)初始化线程,并设置名字
-Thread.currentThread().getName() 获取正在运行的线程的名字
在使用Java命令运行一个Java程序时,JVM会启动一个进程,这个进程至少就会启动两个线程
-主方法是一个线程
-GC垃圾回收线程
线程的休眠
Thread.sleep(毫秒数);
线程的优先级
线程有三种优先级,原理上是优先级越高那么线程就越先执行,但这仅仅是可能是不一定
·高优先级:public static final int MAX_PRIORITY=10
·中等优先级:public static final int NORM_PRIORITY=5
·最低优先级:public static final int MIN_PRIORITY=1
-设置优先级 public final void setPriority(int newPriority)
-获取优先级 public final int getPriority
多线程的实现
要实现线程,在JDK1.5之前有两种方式
·继承Thread类,Thread类是一个支持线程操作的类,只要是该类的子类都可以实现多线 程的所有操作
·实现Runnable接口
在JDK1.5之后提供了Callable接口也可以实现线程的操作,但是目前在开发中一般使用前面 两种
一个Java程序的起点是main方法(其实也叫主线程),在main方法中启动的其他线程叫做之子线程,理所当然它们也有自己的起点方法,这个起点方法就是run方法,run()需要覆写,在启动之后并没有体现多线程的并发性,而是有序的,根本原因是使用run()启动线程的,
所以在启动线程的时候要使用start()方法。
start()方法
start()方法在启动时调用start0()方法,该方法没有方法体,类似于一个抽象方法,使用 native,在Java的开发中有一种技术叫 做JNI(Java Native Interface)技术,该技术是使用Java程序调用本地操作系统的函数,我们在启动线程的时候,操作系统必须为每一个线程分配资源,那么在分配的时候由于操作系统的支持性不同,所以每一种操作系统分配资源方式不一样,那么start0()方法就不能写死,只能定义出一个标准,具体分配实现方式有JVM根据操作系统的不同实现不同的分配方式,这也是表现Java的可移植性的表现之一。
要启动多线程就必须使用start()方法,start()方法中调用start0()完成资源的分配 之后系统再自动调用run()方法。
Runnable接口
在Runnable接口中并没有start()方法,但是在Thread构造方法中,我们可以将Runnable接口作为参数传递过去。public Thread (Runnable target){}
继承Thread:这种方式有单继承的局限,而且不能方便的实现线程之间的数据共享
实现Runnable接口:没有单继承的局限,而且能方便的实现数据之间的共享,实现多线程,使用实现Runnable接口的方式是最好的。
线程的同步
如果线程不同步,那么多个线程访问统一数据的时候就会出现风险
-使用同步代码块
语法:synchronized(this){...}
-使用同步方法
语法 public synchronized void run(){...}
同步的负面效应
·使用同步,那么代码的执行效率就会降低,因为当前线程要等待上一个线程执行完毕之 后才能执行。
·使用同步,有时候会出现死锁现象(但是这个概率非常小)
多线程的生产者,消费者模式
class PublicBox { //产品 private int apple = 0; public synchronized void increace() { while (apple ==5) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } apple++; System. out .println("生成苹果成功!" ); notify(); } public synchronized void decreace() { while (apple ==0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } apple--; System. out.println( "消费苹果成功!" ); notify(); } } class Producer implements Runnable { //生产者 private PublicBox box; public Producer(PublicBox box) { this .box = box; } @Override public void run() { for( int i=0;i<10;i++){ try { System. out .println("pro i:" +i); Thread. sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } box.increace(); } } } class Consumer implements Runnable { //消费者 private PublicBox box; public Consumer(PublicBox box) { this .box = box; } @Override public void run() { for( int i=0;i<10;i++){ try { System. out .println("Con: i " +i); Thread. sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } box.decreace(); } } } public class Test{ public static void main(String []args) { PublicBox box= new PublicBox(); Consumer con= new Consumer(box); Producer pro= new Producer(box); Thread t1= new Thread(con); Thread t2= new Thread(pro); t1.start(); t2.start(); } }
当一个线程访问一个对象的同步方法的时候,如果该线程进入方法之后使用sleep方式休眠,那么在休眠期间其他任何线程不能访问该对象的任何同步方法,也就是说sleep在休眠的时候是不会释放锁的。
当一个线程进入一个对象的同步方法之后使用wait方式休眠的情况下,在休眠的期间,其他线程可以访问该对象的所有同部方法,也就说使用wait方法休眠的线程可以释放锁
·sleep:
|-sleep()是Thread的方法
|-使用sleep休眠的线程会自动醒来
|-使用sleep休眠的线程不会释放锁
·wait():
|-wait()是Obejct类中的方法
|-使用wait休眠的线程需要使用notify或者notifyAll方法唤醒
|-使用wait休眠的线程会释放锁。
请分析一下代码输出“A”和“B”各多少次?
class Productor implements Runnable{ @Override public void run() { for(int i=0;i<50;i++){ try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("A"); } } } class Customer implements Runnable{ @Override public void run() { for(int i=0;i<50;i++){ System.out.println("B"); } } } public class Test { public static void main(String[] args) throws Exception { Thread th1=new Thread(new Productor()) ; Thread th2=new Thread(new Customer()) ; th1.setDaemon(true);//及A设置为守护线程 th1.start(); th2.start(); } }
答:以上代码输出“A”是不确定, 输出“B”是50次
原因是输出A的线程是守护线程,B的线程是非守护线程(用户线程)
守护线程为非守护线程而服务,所以当JVM中如果没有非守护线程的时候,所有的守护线程都会结束,
就算守护线程中的run()方法中的代码还没执行完毕也会被强制结束。但是非守护线程一定会执行完毕,
以上的代码A是由守护线程输出,B是由非守护线程输出,所以A的次数是不定的,B的次数是50固定的
我们最常见的典型的守护线程是CG垃圾回收线程。
标签:cbo ESS 休眠 苹果 reac jdk1.5 日期格式 构造方法 err
原文地址:https://www.cnblogs.com/skynomonarch/p/8976038.html