线程
2015-12-01 23:51
211 查看
进程和线程概念
进程:相对于系统来讲(Win Linux Mac),独立的内存空间,并发性,动态性线程:相对于进程来讲,是进程内部的一个执行单元,内部单一的执行单元,顺序控制流程,共享进程资源
创建线程
1.继承Thread类,复写其run()方法,调用start()方法,启动线程MyThread t = new MyThread (); t.start();
2.实现Runnable接口,实现其run()方法,调用start()方法
MyThread mt = new MyThread (); Thread t = new Thread(mt); t.start();
两种创建进程方法的比较
继承Thread类方式的多线程
- 优势:编写简单
- 劣势:无法继承其它父类
实现Runnable接口方式的多线程
- 优势:可以继承其它类,多线程可共享同一个Thread对象
- 劣势:编程方式稍微复杂,如果需要访问当前线程,需要调用Thread.currentThread()方法
调用start()方法启动线程和直接调用run()方法的区别
调用start()方法,会申请新的线程,开辟新的线程空间去执行run()方法中的内容
调用run()方法,只是由当前线程去调用run()方法,不会创建新的线程,仅将其当成一个普通方法调用
多线程的优势(重点)
多线程使系统空转时间减少,提高CPU利用率进程间不能共享内存,但线程之间共享内存非常容易
使用多线程实现多任务并发比多进程的效率高
Java语言内置多线程功能支持,简化了Java的多线程编程
线程状态
新生 创建新的线程对象
运行 调用start()方法
阻塞
1.sleep(long time) 睡眠time毫秒后,自动唤醒继续运行
2.join()加入 A线程加入到B线程,B线程等待A线程运行完毕再继续向下执行
3.yield()暂停瞬间,然后继续执行
死亡 整个线程的run()方法的代码块运行完毕
线程锁
synchronization(){ }同步代码块 多个线程中存在使用同一把锁的代码块,多个线程会抢这一把锁,抢到的进入同步代码块,剩下的线程全在外面阻塞,阻塞到进入的线程运行完,该线程会释放锁,所有阻塞的线程继续开始抢锁。同步方法 public synchronized void xxx (){ },同步方法的锁,就是锁住的对象就是调用该方法的对象
注意 :在拥有同步方法的类中,锁住的是该类的实例化的对象
线程同步的必要性
线程间通信
wait()和notify()当执行了wait()方法后,本线程终止,将锁释放给正在等待该锁的线程
当执行了notify()方法后,线程会唤醒正在等待该锁的对象,但是唤醒后不是立即执行,而是等调用notify()方法的线程执行完同步代码块之后,才开始抢占执行。
Timer
定时器的使用首先要实例化Timer对象,
然后要重写一个类继承TimerTask类,在复写其中的run()方法
然后调用Timer()对象的schedule(TimerTask task, long delay, long period)
第一个参数是继承TimerTask类的实例化对象
第二个参数是延时多久开始执行其run()方法
第三个参数是run()方法循环的间隔时间
public class Test { public static void main(String[] args) { Timer timer=new Timer(); timer.schedule(new MyTimerTask(), 2000 ,500); } } public class MyTimerTask extends TimerTask{ private int i=0; public void run() { System.out.println("正在计时:"+i++); } }
反射详解
反射就是可以通过对象实例或者类名来获取Class对象,通过Class对象的各种方法,可以获得该类的各种信息,包括属性,方法,构造器,返回值类型,属性类型等等。Class 类的抽象 Person Dog Car
Field 属性的抽象
Method 方法的抽象
Constructor 构造器的抽象
可以通过反射的机制,给对象中的属性进行赋值操作
public class ReflectionTest { public static void main(String[] args) { Person zhangsan=new Person(); System.out.println(zhangsan.getName()); //此Person中不存在一个可以访问方法去修改名字 //可以使用反射去修改zhangsan这个对象的name //1得到Person的Class对象 Class<Person> zhangsanClass=(Class<Person>) zhangsan.getClass(); try { //2得到Person类中名称是name的字段 Field name=zhangsanClass.getDeclaredField("name"); //3取消反射时的java语言访问限制 name.setAccessible(true); //4使用field修改zhangsan的name的值,因为Person中的name是private的,所以会报错,其他修饰符的话不会报错 name.set(zhangsan, "张三"); //5重新打开反射时的java语言访问限制,以后访问还要检查 name.setAccessible(false); System.out.println(zhangsan.getName()); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } public class Person { private String name ;//zheshishenme a private String sex; public String getName() { return name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
设计模式
Dao模式只有属性和set get方法
单例模式
在要单例化的类中① 私有化构造器,不允许外部使用new关键字创建对象
② 声明一个静态的私有的Person对象
③ 提供一个静态的公有的同步方法供外部访问,返回值类型是该类 为什么使用synchroized防止多个线程同时访问这个方法 静态同步方法的锁是指的类本身
④ 在该方法中添加限制
public class Person { private String name; private String sex; //创建一个静态的私有的该类对象,声明为静态只能有一个这个对象的实例 private static Person person; //私有化构造器 private Person() { } //创建一个共有的静态的同步方法,声明为同步方法可以限制多个线程同时访问的问题,声明为静态可以通过类名调用 public synchronized static Person newInstance() { //在其中添加限制,若不为空,就实例化对象,否则仅返回其对象 if (person==null) { person=new Person(); } return person; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } public class Test { //所有输出的内容hashcode是一样的,表示是同一个对象 public static void main(String[] args) { Person zhangsan=Person.newInstance(); System.out.println(zhangsan); Person lisi=Person.newInstance(); System.out.println(lisi); new Thread(new Runnable() { public void run() { Person wangwu=Person.newInstance(); System.out.println(wangwu); } }).start(); new Thread(new Runnable() { public void run() { Person zhaoliu=Person.newInstance(); System.out.println(zhaoliu); } }).start(); } }
简单工厂模式
创建一个工厂,使用这个工厂创建这个类的对象创建一个配置文件properties格式,用Properties类从中读取类的信息,根据类的信息用Class的forName(String str),获取累的对象,
再用该对象实例化要生成的对象实例
要改变生成的对象实例时候,就不用重新编译代码,仅仅修改配置文件的类的信息就可以了
另外如果要扩展程序的话,对源代码基本不用改变,直接生成你要添加的类的代码即可
public class Person { public void speak() { System.out.println("人类会说话"); } } public class Teacher extends Person{ @Override public void speak() { System.out.println("老师会讲课"); } } public class PersonFactory { public Person newInstance() { Person person=null; Properties pro=new Properties(); try { //解析配置文件 pro.load(new FileInputStream("config.properties")); //从配置文件中读取类的信息 String str=pro.getProperty("classname"); //Class类根据类名生成Class的对象 Class name=Class.forName(str); //由Class对象生成对应类的实例 person=(Person) name.newInstance(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } return person; } } public class Test { public static void main(String[] args) { PersonFactory factory=new PersonFactory(); Person person=factory.newInstance(); //根据生成对象的不同,输出相应改变 person.speak(); } }
配置文件如下
知识漏洞
static
在一个类中,static修饰的类的属性,不管实例化多少个对象,该属性都只有一个,并且对每一个实例化对象共享。PrintWriter
print()和println()的区别- print()仅仅是打印输出
- println()打印输出,并且终止当前行的输出
相关文章推荐
- hdoj2018--母牛故事
- IEEE Std 802.11™-2012 1. Overview
- 阿里云装wamp提示缺少msvcr110.dll解决办法
- atom安装activate-power-mode插件(Win7x86)
- Java中普通代码块,构造代码块,静态代码块区别及代码示例
- 安卓仿IOS开关设计
- 【转】G40-70、G50-70联想小新笔记本SR1000随机Linux改Windows 7系统操作指导
- 南大软院二十一天成神计划
- STM32 PCB触摸按键(RC检测法)
- 森林病虫防治系统(九)
- Linux内核zero-copy小试牛刀(加注释)
- Lighty的Chunk设计
- python核心编程-函数-装饰器
- 培训机构毕业的程序员被歧视的背后逻辑
- DNS域名解析过程
- css中的注意项,可能会帮助到大家哦!
- windows溢出保护原理与绕过方法概览
- Android-Property Animation(属性动画)
- session和cookie
- 永久修改python默认的字符编码为utf-8