JAVA自学笔记24

1、能使用同步代码块就使用同步代码块,除非锁对象是this,就可以考虑使用同步方法。静态方法的锁是类的字节码对象。
2、JDK5新特性
1)接口Lock
void Lock()//获取锁
void unlock()//释放锁

ReentrantLock:实现类

public class SellTicketDemo{
public stsatic void main(String args[]){
Thread t1=new Thread(st,"窗口1");
Thread t2=new Thread(st,"窗口2");
Thread t3=new Thread(st,"窗口3");t1.start();
t2.start();
t3.start();
}
}publlic class SellTicket implements Runnable{
private int tickets=100;
//定义锁对象
private Lock lock=new ReentrantLock();
public void run(){
//加锁
try{
lock.lock();
if(tickets>0){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖"+(tickets--)+"张票")
})
finally{//解锁
lock.unlock();}//避免程序出现错误而无法解锁
}
}

2)死锁问题
①同步弊端:效率低,容易产生死锁问题。如果出现了同步嵌套,就容易出现死锁问题
②是指两个或者两个以上的线程在执行过程中,因争夺资源产生的一种相互等待的现象。

public class MyLock{//创建两把锁对象
public static final Object ObjA=new Object();
public static final Object ObjB=new Object();
}public class DieLock extends Thread{private boolean flag;public DieLock(boolean flag){
this.flag=flag;public void run(){
if(flag){
Synchronized(MyLock.objA){
System.out.println("if objA");
Synchronized(MyLock.objB){
System.out.println("if objB");
}
}
}else{
synchronized(MyLock.objB){
System.out.println("else objB");
Synchronized(MyLock.objA){
System.out.println("else objA");
}
}
}
}
}
public class DieDemo{public static void main(String[] args){
DieLock dl1=new DieLock(true);
DieLock dl2=new DieLock(false);dl1.start();
dl2.start();
}
}

3)线程间的通信
不同种类的线程间针对同一个资源的操作,设置线程(生产者),获取线程(消费者)

//学生类(资源类)
public class Student{String name;
int age;
}//设置线程
public class SetThread implements Runnable{private Student s;
private int x=0;
public SetThread(Student s){
this.s=s;
}
public void run(){
synchronized(s){while(true){
if(x%2==0){
s.name="cc";
s.age=18;
}else{
s.name="dd";
s.age=13;
}
x++;
}
}
}}//消费线程
public class GetThread implements Runnable{implements Runnable{
private Student s;
public SetThread(Student s){
this.s=s;
}
public void run(){
synchronized(s){while(true){System,out,println(s.name);
}}}
}//测试类
public class StudentDemo{//创建资源
Student s=new Student{};//设置和获取的类
pubic static void main {String args[]){
SetThread st=new SetThread(s);
GetThread gt=new GetThread(s);//线程类
Thread t1=new  Thread(st);
Thread t1=new  Thread(gt);//启动线程
t1.start();
t2.start();
}

4)等待唤醒机制
图解:

void wait();
在其他线程调用此对象的notify()或notifyAll()方法前,导致该线程等待
void notify()
唤醒在此对象监视器等待的单个线程
void notifyAll()
唤醒在此对象监视器等待的所有线程

//学生类(资源类)
public class Student{String name;
int age;
boolean flag;
}//设置线程
public class SetThread implements Runnable{private Student s;
private int x=0;
public SetThread(Student s){
this.s=s;
}
public void run(){
while(true){synchronized(s){
if(s.flag){
s.wait();}
if(x%2==0){
s.name="cc";
s.age=18;
}else{
s.name="dd";
s.age=13;
}
x++;
s.flag=true;
s.notify();
}
}
}}//消费线程
public class GetThread implements Runnable{implements Runnable{
private Student s;
public SetThread(Student s){
this.s=s;
}
public void run(){
synchronized(s){
if(!s.flag){
s.wait();
}
while(true){
System,out,println(s.name);
s.flag=false;
s.notify();
}}}
}//测试类
public class StudentDemo{//创建资源
Student s=new Student{};//设置和获取的类
pubic static void main {String args[]){
SetThread st=new SetThread(s);
GetThread gt=new GetThread(s);//线程类
Thread t1=new  Thread(st);
Thread t1=new  Thread(gt);//启动线程
t1.start();
t2.start();
}

线程的状态转换图:

3、线程组
1)java使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,java允许程序直接对线程组进行控制
默认情况下,所有的线程都属于主线程组
public final ThreadGroup getThreadGroup()
也可以给线程设置分组
Thread(ThreadGroup group,Runnable target,String name)

public class MyRunnable implements Runnable{public void run(){
for(int x=0;x<0;x++){
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
public class void ThreadGroupDemo{public static void main(String args[]){
MyRunnable my=new MyRunnable();
Thread t1=new Thread(my,"cc");
Thread t2=new Thread(my,"dd");ThreadGruop tg1=t1.getThreadGruop();
ThreadGruop tg2=t2.getThreadGruop();
//获取线程组名
String name1=tg1.getName();//main
String name2=tg2.getName();//main//修改线程所在组
method1();
}
}
private static void method1(){
ThreadGroup tg=new ThreadGroup("这是新的组");MyRunnable my=new MyRunnable();
Thread t1=new Thread(tg,my,"cc");
Thread t1=new Thread(tg,my,"dd");
}

//生产者消费者案例优化

//学生类(资源类)
public class Student{private private String name;
int age;
private boolean flag;public synchronized void set(String name,int age){
if(this.flag){
this.wait();
}
}
//设置数据
this.name=name;
this.age;
//修改标记
this.flag=true;
this.notify();
}
public synchronized void get(){
if(!this.flag){
this.wait();
}
}
System.out,println(this.name);
this.flag=false;
this.notify();
}//设置线程
public class SetThread implements Runnable{private Student s;
private int x=0;
public SetThread(Student s){
this.s=s;
}
public void run(){
while(true){
if(x%2==0){
s.set("cc",23);
}else{
s.set("dd",23);
}
x++;
}
}
}}//消费线程
public class GetThread implements Runnable{implements Runnable{
private Student s;
public SetThread(Student s){
this.s=s;
}
public void run(){
synchronized(s){
if(!s.flag){
s.wait();
}
while(true){
s.get();
}}}
}//测试类
public class StudentDemo{//创建资源
Student s=new Student{};//设置和获取的类
pubic static void main {String args[]){
SetThread st=new SetThread(s);
GetThread gt=new GetThread(s);//线程类
Thread t1=new  Thread(st);
Thread t1=new  Thread(gt);//启动线程
t1.start();
t2.start();
}

4、线程池
1)程序启动一个新线程的成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好地提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
在JDK5之前,必须手动实现自己的线程池,从JDK5开始,Java支持内置线程池。
JDK5新增了一个Exexutors工厂类来产生线程池,有如下几个方法:
public static ExecutorsService newCacheThreadPool()
开启具有缓存功能的线程池
public static ExecutorsService newFixedThreadPool(int nThreads)
创建指定个线程的线程池
public static ExecutorsService newSingleThreadExecutor()
创建1个线程池
这些方法的返回值是ExecutorsService对象。该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的线程。

public class ExecutorsDemo{public static void main(String args[]){
//创建一个线程池对象,控制要创建2个线程对象
ExecutorService pool=Executors.newFixedThreadPool(2);
//可以执行Runnable对象或者Callable对象代表的线程
pool.submit(new MyRunnable());
pool.submit(new MyRunnable());//结束线程池
pool.shutdown();
}
}public class MyRunnable implements Runnable{public void run(){
for(int x=0;x<100;x++){
System.out.println(Thread.currenThread().getName()+":"+x);
}
}
}}
}
//多线程方式3的实现方式
可以有返回值,可以做出异常,但代码过于复杂一般不用
接口Callablepublic class CallableDemo{ExecutorService pool=Executors.newFixedThreadPool(2);pool.submit(new MyCallable());
pool.submit(new MyCallable());
}public class MyCallable implements Callable{for(int x=0;x<100;x++){
System.out.println(Thread.currenThread().getName()+":"+x);}
public Object call() throws Exception{
return null;
}
}

5、匿名内部类实现多线程
new Thread(){代码…}.start();
New Thread (new Runnable(){代码…}}.start();

//
public class ThreadDemo{
public static void main(String args[]){
//继承Thread实现多线程new Thread(){
//重写run()方法
public void run(){
for(int x=0;x<100;x++){
System.out.println(Thread.currenThread().getName()+":"+x);
}
}
}.start();//实现Runnable接口来实现多线程
new Thread(new Runnable(){
public void run(){
for(int x=0;x<100;x++){
System.out.println(Thread.currenThread().getName()+":"+x);
}
}
}).start();
}//走子类对象
new Thread(new Runnable(){
public void run(){
for(int x=0;x<100;x++){
System.out.println("Hello"+":"+x);
}
}
}){
public void run(){
for(int x=0;x<100;x++){
System.out.println("World"+":"+x);
}
}
}.start();
}
}

6、定时器
1)定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后线程的方式执行,在java中,可以通过Timer和TimerTask类来实现定义调度的功能
2)Timer
public Timer()
//创建一个新的计时器
public void schedule(TimerTask task,long delay)
安排在指定延迟后执行指定的任务
public void schedule(TimerTask task,long period)
安排指定的任务从指定的延迟后开始进行重复的固定延迟执行
3)TimerTask
public abstract void run()
此计时器任务要执行的操作
public boolean cancel()
//终止此计时器,丢弃所有当前已安排的任务

public class TimerDemo{public static void main(String args[]){
//创建定时器对象
Timer t=new Timer();
t.schedule(new MyTask(t),3000);
}
}class MyTask extends TimerTask{private Timer t;
public MyTask(){}
public MyTask(Timer t){
this.t=t;
}public void run(){
System.out.println("爆炸");
t.cancel();
}
}
//定时删除指定的带内容目录
class DeleteFolder extends TimerTask{public void run(){
File file=new File("demo");
deleteFolder(srcFolder);
}
public void deleteFolder(File srcFolder){
File[] fileArray=srcFolder.listFiles();
if(fileArray!=null){
for(File file:fileArray){
if(file.isDirectory()){
deleteFolder(file);
}else{
file.delete();
}
}
srcFolder.delete();
}
}
}
public class TimerTest{public static void main(String args[]){
Timer t=new Timer();
String s="2018-8-23 15:52:24";
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=sdf.parse(s);t.schdule(new DeleteFolder(),d);
}
}

7、多线程常见面试题回顾
1)多线程有几种实现方案,分别是哪几种。
两(三)种。继承Thread类,实现Runnable接口,(实现Callable接口)

2)同步有几种方式,分别是什么?
同步代码块
同步方法

3)

8、面向对象思想设计原则及常见设计模式
1)面向对象思想设计原则

2)设计模式
设计模式是一套被反复使用,多数人知晓的,经过分类编目的代码设计经验总结。使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码的可靠性。

转载于:https://www.cnblogs.com/Tanqurey/p/10485333.html

JAVA自学笔记24相关推荐

  1. JAVA自学笔记07

    JAVA自学笔记07 1.构造方法 1) 例如:Student s = new Student();//构造方法 System.out.println(s);// Student@e5bbd6 2)功 ...

  2. JAVA自学笔记22

    JAVA自学笔记22 1.操作基本数据类型的流 DataInputStream DataOutputStream 数据输出流允许应用程序以适当方式将基本的Java数据类型写入输出流中.然后,应用程序可 ...

  3. JAVA自学笔记21

    JAVA自学笔记21 1.转换流 由于字节流操作中文不是非常方便,因此java提供了转换流 字符流=字节流+编码表 1)编码表 由字符及其对应的数值组成的一张表 图解: 2)String类的编码和解码 ...

  4. JAVA自学笔记08

    JAVA自学笔记08 1.构造方法私有,外界就不能再创建对象 2.说明书的制作过程 1)写一个工具类,在同一文件夹下,测试类需要用到工具类,系统将自动编译工具类:工具类的成员方法一般是静态的,因此在测 ...

  5. JAVA自学笔记25

    JAVA自学笔记25 1.GUI 1)图形用户接口,以图形的方式,来显示计算机操作的界面,更方便更直观 2)CLI 命令行用户接口,就是常见的Dos,操作不直观 3) 类Dimension 类内封装单 ...

  6. JAVA自学笔记23

    JAVA自学笔记23 1.多线程 1)引入: 2)进程 是正在运行的程序.是系统进行资源分配和调用的独立单位.每一个进程都有它自己的内存空间和系统资源. 多进程: 单进程的计算机只能做一件事情,而现在 ...

  7. Java自学笔记——Java面向对象——04.抽象类、接口、内部类

    Java 面向对象各节 Java自学笔记--Java面向对象--01.回顾方法 Java自学笔记--Java面向对象--02.构造器.类和对象 Java自学笔记--Java面向对象--03.封装.继承 ...

  8. 廖雪峰Java自学笔记------Java简洁

    廖雪峰Java自学笔记------Java简洁 这是专门针对小白的零基础Java教程. 为什么要学Java? 因为Java是全球排名第一的编程语言,Java工程师也是市场需求最大的软件工程师,选择Ja ...

  9. Java自学笔记总结04

    Java自学笔记04 一.Lambda表达式 1.1 函数式编程思想概述 1.2 体验Lambda表达式 1.3 Lambda表达式的标准格式 1.4 Lambda表达式的使用 1.5 Lambda表 ...

最新文章

  1. php 哲学家进餐,IPC问题-哲学家就餐(示例代码)
  2. 从硬件到软件 统一沟通将引领通讯市场
  3. 手动制作自己想的语谱图
  4. mysql数据库优化韩顺平_韩顺平 Mysql数据库优化(一) 优化概述
  5. 使用ArcGIS JavaScript API 3.18 加载天地图
  6. controller调用controller的方法_SpringCloud(5):Feign整合Ribbon和Hystrix来进行远程调用与服务熔断...
  7. c++ mqtt客户端_MQTT详解及百度物接入连接手机测试(含源码) 秦子帅
  8. 一文看懂PHP如何实现依赖注入
  9. 继承viewgroup
  10. 台式计算机操作系统的安装,Win10X电脑操作系统可以装在台式机吗?
  11. 寂静岭2java攻略_寂静岭2攻略
  12. UE4 Slate四 SlateUI如何做动画
  13. Android预置默认输入法
  14. python计算十年平均录取率_如何在Python中使用Pandas计算多年平均值
  15. Linux设置登录密码错误次数限制
  16. Google.cn刚上不去了
  17. 服务器被植入广告文件,[求助]服务器后台被植入webshell,看不懂什么意思
  18. 关于QT跨平台和编译器的理解
  19. 如何修改计算机设备的登录名称
  20. EOL while scanning string literal

热门文章

  1. IO消耗和处理器消耗
  2. shell实例第23讲:每天定时备份nginx日志
  3. oracle: 在sqlplus中,执行sql语句
  4. java: http请求和响应
  5. SQLite安装、编译与应用
  6. xmlWriter以UTF-8格式写xml问题
  7. 黑客演示通过空中电视信号DVB-T攻击智能电视机
  8. 阿里内核月报2015年03月
  9. c# 连接Redis报错:WRONGTYPE Operation against a key holding the wrong kind of value:类型搞混弄出的错误...
  10. Struts2文件上传