• JAVA自学笔记24


    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的实现方式
    可以有返回值,可以做出异常,但代码过于复杂一般不用
    接口Callable
    
    public 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)设计模式
    设计模式是一套被反复使用,多数人知晓的,经过分类编目的代码设计经验总结。使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码的可靠性。

  • 相关阅读:
    jQuery--百度百科
    JSP--百度百科
    servlet--百度百科
    java web--百度百科
    软件测试--百度百科
    HTML--百度百科
    CSS--百度百科
    JavaScript--百度百科
    js识别不同浏览器
    【cocos2dx开发技巧10】cocosStudio的集成以及c++11的新特性
  • 原文地址:https://www.cnblogs.com/Tanqurey/p/10485333.html
Copyright © 2020-2023  润新知