28.1 Java进阶之线程的概念,创建线程和任务,Thread类,线程池,线程同步,锁同步

声明:本博客代码完整,所有实例均可正常运行,代码仓库链接在文章底部,需要的可自取。

Java中重要机制之一就是支持内部多线程:在一个Java程序中允许同时运行多个任务。

1.线程概念

1.1 什么是线程?

我们写一段程序,然后运行这段程序,当我们运行这段程序,实际上就启动了一个线程,也就是说线程是运行代码程序的单位。 而这个代码程序,就是一个任务。
线程本质上讲就是执行任务的对象,如果把线程比作一台打印机,那么任务就是一份需要打印的文档。
线程提供了运行一个任务的机制,对于Java, 可以在一个程序中并发地启动多个线程,这些线程可以同时运行。

1.2 使用多线程的好处

多线程可以使程序执行的更快,让程序的交互性更强,从而使得程序执行效率的提升。
简单来说,如果当我们写一段程序处理一份数据时,如果我们使用多线程编程去解决这个问题,我们能更快的获得结果。
如果使用多线程让程序同时执行不同类型的任务,就能让程序同时服务多个不同的请求,请求和请求之间可以不用排队,很快就能得到响应。

2.Java如何定义任务和线程

本节主要学习如何使用Java语言编写多线程程序。

2.1 任务定义

在Java中定义一个任务就是定义实现Runnable接口的一个类(Runnable中只有一个run方法)

2.1.1 Runnable接口

// 任务接口,Java中定义一个任务类必须要实现这个接口
public interface Runnable {
    public abstract void run();
}

可以看到,Runnable只有一个方法的定义,就是run,也就是说每个任务需要实现这个接口,给出run的程序,线程具体执行的代码就是这个run的实现。
例如下面定义一个名为PrintChar的任务类:

public class PrintChar implements Runnable{
    
    private final char charToPrint;

    private final int times;

    public PrintChar(char c,int t) {
        charToPrint=c;
        times=t;
    }
    @Override
    public void run() {
        for(int i=0;i<times;i++) {
            System.out.print(charToPrint);
        }
    }
}

定义好这个类后,当我们学习了Thread的使用,便可以创建任务对象,然后让线程去执行它。

2.2 线程定义

在Java中,我们只需要新建一个Thread对象,然后将具体任务对象作为参数传入,接着执行start方法即可开启一个线程并执行一个任务。
例如:

public static void main(String[] args) {
    //新建任务对象:这里新建了两个任务
    Runnable printA=new PrintChar('a',100);
    Runnable printB=new PrintChar('b',100);
    //新建线程对象:这里新建了两个线程
    Thread thread1=new Thread(printA);
    Thread thread2=new Thread(printB);
    //并行运行thread1,thread2
    thread1.start();
    thread2.start();
}

在这里插入图片描述

这样的话,在程序中,这两个线程是不会相互影响的同时运行的,如果使用单线程(常规编程),那么花费的时间会更长。

3.学习Thread类

通过上面的学习,我们写出了第一个多线程程序,可以看到多线程涉及的类主要有两个,一个是我们自定义的任务类,另一个就是Jdk提供了Thread类,下面我们对其进行学习。
下面我们看下这个类的类图:
在这里插入图片描述

3.1 Thread实现了Runnable接口

从上面我们可以看出Thread也实现了Runnable接口,所以,我们是不是也能通过Thread定义自己的任务呢?
答案是可以的:

public class TaskThreadDemo extends Thread {

    private final char charToPrint;
    private final int times;

    public TaskThreadDemo(char charToPrint, int times) {
        this.charToPrint = charToPrint;
        this.times = times;
    }

    public void run(){
        for(int i=0;i<times;i++) {
            System.out.print(charToPrint);
        }
    }
}

然后使用它:

public static void main(String[] args) {
    Thread thread1 = new TaskThreadDemo('a',100);
    Thread thread2 = new TaskThreadDemo('b',100);
    thread1.start();
    thread2.start();
}

在这里插入图片描述

但是这种方法并不常用,因为,让任务类去继承Thread并不是一个灵活的做法,在Java中一个类只能继承一个类,但可以实现多个接口,我们应该让任务类去继承更有价值的类。

3.2 Thread中的方法学习

可以通过下面的例子进行学习

public static void main(String[] args) throws InterruptedException {
    //创建任务
    Runnable printA=new PrintChar('a',5);
    Runnable printB=new PrintChar('b',5);

    //新建线程
    Thread thread1 = new Thread(printA);
    Thread thread2 = new Thread(printB);
    //理论上优先级值越小, 执行越优先
    thread1.setPriority(10);
    thread2.setPriority(1);
    //并行开始运行thread1,thread2
    thread1.start();
    thread2.start();

    //等待thread1,thread2执行结束
    thread1.join();
    thread2.join();
    System.out.println();

    /**
     * 利用isAlive对线程状态进行检查
     */
    while (true){
        //让当前线程进入休眠状态
        Thread.sleep(1000);
        boolean thread1Alive = thread1.isAlive();
        boolean thread2Alive = thread2.isAlive();
        if(!thread1Alive&&!thread2Alive){
            System.out.println("thread1 和 thread2 运行完毕!");
            break;
        }
        if(thread1Alive) System.out.println("thread1 正在运行");
        if(thread2Alive) System.out.println("thread2 正在运行");
    }

}

在这里插入图片描述

4.线程池

操作系统创建线程的开销是比较大的,我们不能在程序中无止境的创建线程,但是我们可以利用已经存在的线程进行多线程任务执行,这时,我们就可以使用线程池来达到目的了。

我们可以使用线程池来高效执行任务
前面的对单个任务创建一个线程显然对大量任务而言使不够高效的,原因是:为每个任务开始一个新线程可能会限制吞吐量并且造成性能降低。线程池是管理并发执行任务个数的理想方法。
Java提供Executor接口,ExecutorService接口,Executors类来支持线程池。

他们类图如下:
在这里插入图片描述

4.1 Executor接口

此接口仅定义了一个方法execute, 这个方法相当于Thread中的start, 它让线程吃执行传入其中的任务。

//线程池用此方法执行传入的任务
void execute(Runnable command);

4.2 ExecutorService接口

这个就是接口是线程池接口,其中定义了线程池包含的方法

public interface ExecutorService extends Executor {
    
    //关闭线程池,已经提交的任务继续执行,不接受新任务
    void shutdown();
    
    //尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。
    List<Runnable> shutdownNow();
    
    //如果线程池已经关闭,则返回true
    boolean isShutdown();
    
    //如果执行shutdown后,线程池中所有任务结束,则返回true
    boolean isTerminated(); 
    
    //执行shutdown后,进入阻塞等待状态直到所有任务都完成/超时
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
    
    // 提交一个带有返回值的任务
    <T> Future<T> submit(Callable<T> task);

    //提交一个任务并返回一个Future对象
    //这个Future对象能在在任务完成后使用get得到result对象
    <T> Future<T> submit(Runnable task, T result);

    //提交一个任务并返回一个Future对象
    //这个Future对象能在任务完成后使用get得到null
    Future<?> submit(Runnable task);

    // 执行提交的集合中所有的任务并返回一个Future列表
    // 可以使用Future.isDone来判断任务是否执行完成,如果完成返回true
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;

    //执行提交的集合中所有的任务并返回一个Future列表(任务结束或超时后可获取状态)
    //可以使用Future.isDone来判断任务是否执行完成,如果完成返回true
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;

    //执行给顶的任务列表,返回已成功完成的任务结果
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;

    //执行给顶的任务列表,返回已成功完成的任务结果,如果超时则抛出异常
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

4.3 AbstractExecutorService类

这个类提供了线程池接口的抽象实现,提供了一些可复用的代码。
感兴趣的同学可以学习下, 本节的目的不是解读源码,所以略。

4.4 ThreadPoolExecutor

它是ExecutorService的一个具体实现。
它继承了AbstractExecutorService抽象类,它是线程池的一种具体实现。
我们可以直接使用它来构造自己的线程池。
但是由于这个类的使用比较复杂,所以我们可以先使用Jdk中对这个类的封装。

4.5 Executors类

这个类是线程池的一个工厂类,它提供了一些ThreadPoolExecutor的对象生成方法,
例如:

//创建一个指定线程数的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

//创建一个不限数量的线程池,当需要线程时,线程池会新建一个
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

就上面两种线程池而言,一般前者更安全,因为后者存在线程超量的问题。

4.6 使用线程池

public class ThreadPoolStudy {

    public static void main(String[] args) {

        //创建一个线程池,且里面最多容纳1个线程
        ExecutorService executor= Executors.newFixedThreadPool(1);

        //添加任务到线程池中,实际上,这里的两个任务的执行时串行的
        //因为前面定义线程池中线程的数量为1,只有一个线程执行任务
        executor.execute(new PrintChar('a',5));
        executor.execute(new PrintChar('b',5));
        //关闭执行器
        executor.shutdown();

    }

    static class PrintChar implements Runnable{

        private final char charToPrint;
        private final int times;

        public PrintChar(char c,int t) {
            charToPrint=c;
            times=t;
        }
        public void run() {
            for(int i=0;i<times;i++) {
                System.out.print(charToPrint);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

在这里插入图片描述

5. 关键字线程同步

线程同步用于协调相互依赖的线程的安全执行,保存程序中数据不出问题。
在计算机中存在这样一个问题:如果一个共享资源被多个线程同时访问,则这个共享资源可能存在会遭到破坏的风险。
因此为了避免这种情况发生,我们应该防止多个线程同时进入程序的某一特定修改共享资源的部分,这一部分称为临界区(critical region)

5.1 同步方法

在Java中,我们可以用关键字synchronized来保证多线程安全执行,以便一次只有一个线程可以访问这个方法,被synchronized修饰的方法我们可以称之为同步方法。

一个同步方法在执行之前需要加锁。锁是一种实现资源排他使用的机制。
对于实例同步方法,要给调用该方法的对象加锁。
在这里插入图片描述

对于静态同步方法,要给这个类加锁。

5.1.1 实例演示

// 完整代码地址在文章最后
public static void main(String[] args) {
    ExecutorService executorService = Executors.newFixedThreadPool(1000);
    Account account = new Account();
    UnSynAccount unSynAccount = new UnSynAccount();

    for(int i=0;i<500;i++)
        executorService.execute(account);
    for(int i=0;i<500;i++)
         executorService.execute(unSynAccount);

    executorService.shutdown();

    while (true){
        if(executorService.isTerminated()){
            System.out.println(account.toString());
            System.out.println(unSynAccount.toString());
            break;
        }
    }

}

在这里插入图片描述

5.2 同步语句

如果同步方法中只有几行代码是临界区,那么仅仅为了这几行临界区而牺牲整个方法的性能,这显然不值得,所以Java中存在同步语句机制来解决这一问题。
同步语句允许设置同步方法中的部分代码,而不必是整个方法,这大大增强了程序的并发能力。
当执行方法中的某一代码块时,同步语句不仅可用于对this对象的加锁,还可用于对任何对象加锁,这个代码块称为同步块(synchronized block)
其一般形式为:

synchronized(expr){
  statements;
}

表达式expr求值结果必须是一个对象的引用,如果对象已经被另一个线程锁定,则在解锁之前该线程将被阻塞,当获准对一个对象加锁时,该线程执行同步块中的语句,然后解除锁。
实例演示:

// 完整代码地址在文章最后
public static void main(String[] args) {
    ExecutorService executorService = Executors.newFixedThreadPool(1000);
    Account account = new Account();
    UnSynAccount unSynAccount = new UnSynAccount();
    SynBlockAccount blockAccount = new SynBlockAccount();

    for(int i=0;i<500;i++)
        executorService.execute(blockAccount);
    for(int i=0;i<500;i++)
         executorService.execute(unSynAccount);

    executorService.shutdown();

    while (true){
        if(executorService.isTerminated()){
            System.out.println(blockAccount.toString());
            System.out.println(unSynAccount.toString());
            break;
        }
    }
}

在这里插入图片描述

6.API加锁实现同步(Lock类)

我们可以显式地采用锁对象和状态来同步线程。
Java可以显式地加锁,这给协调线程带来了更多的控制功能,在Java中提供了Lock接口来定义相应的锁机制。
我们可以使用Lock具体的实现来实现加锁操作。
在这里插入图片描述

ReentrantLock是Lock的一个具体实现。

6.1 Lock接口

Lock接口中定义如下

//得到一个锁
void lock();
//获得一个锁如果线程没被中断
void lockInterruptibly() throws InterruptedException;
//当锁没有被占用,才获取锁。
boolean tryLock();
//尝试获取锁直到获取或超时
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
//释放锁
void unlock();
//返回一个绑定了锁的Condition
Condition newCondition();

6.2 ReentrantLock

ReentrantLock是对Lock的具体实现,我们可以使用它来实现对临界区的保护,使用方式如下:

Lock lock = new ReentrantLock();
lock.lock();
try{
    //临界代码块
}catch(Exception e){
    
}finally{
    //确保锁能被正常释放
    lock.unlock();
}

这个结构能确保任何时刻只有一个线程进入临界区。 一旦一个线程锁定了锁锁对象,其他任何线程都无法正常执行lock语句。 当其他线程调用lock时,他们会暂停,直到前面的线程释放了这个锁对象。

6.2.1 演示实例

public class LockStudy {
    private static Account account = new Account();
    public static void main(String[] args) {
        //创建线程池
        ExecutorService executor= Executors.newCachedThreadPool();
        //循环添加任务
        for(int i=0;i<1000;i++) {
            executor.execute(new AddAPennyTask());
        }
        // 关闭线程池
        executor.shutdown();

        //所有任务都执行完
        while(true) {
            if(executor.isTerminated()){
                System.out.println("任务执行完毕!!");
                break;
            }
        }

        System.out.println("what is balance? "+account.getBalance());
    }

    public static class AddAPennyTask implements Runnable{
        public void run() {
            account.deposit(1);
        }

    }

    private static class Account{
        //创建一个互斥锁
        private static final Lock lock = new ReentrantLock();
        private int balance = 0;
        public int getBalance(){
            return balance;
        }
        public void deposit(int amount) {
            //获取一个锁
            lock.lock();
            try{
                int newBalance=balance+amount;
                Thread.sleep(5);
                balance=newBalance;
            } catch(InterruptedException ex) {
                System.out.println("线程中断!!");
            } finally{
                //释放锁
                lock.unlock();
            }
        }
    }
}

在这里插入图片描述

7.本章完整代码地址

Java基础学习/src/main/java/Progress/exa28_1 · 严家豆/Study - 码云 - 开源中国 (gitee.com)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
第1篇 Java开发必备基础 第1章 搭建Java开发环境 1.1 Java的过去、现在和未来 1.1.1 Java的历史 1.1.2 Java的语言特点 1.1.3 Java API简介 1.1.4 Java未来发展 1.2 Java程序设计环境 1.2.1 命令行工具——JDK 6.0 1.2.2 安装工具包JDK 1.2.3 设置JDK环境 1.2.4 集成开发环境安装——MyEclipse 8.5 1.2.5 MyEclipse的一些常用操作 1.3 创建和运行Java程序 1.3.1 手工创建、编译和运行Java程序 1.3.2 在MyEclipse 8.5中创建、运行、调试和管理Java项目 1.4 小结 第2章 Java面向对象编程 2.1 面向对象的一些概念 2.1.1 面向对象涉及的概念 2.1.2 类和对象 2.2 面向对象的一些特性 2.2.1 继承特性 2.2.2 多态特性 2.2.3 封装特性 2.3 Java中实现的面向对象特性 2.3.1 定义类 2.3.2 创建对象 2.3.3 实现继承 2.3.4 实现多态 2.3.5 实现封装 2.4 小结 第3章 Java新特性 3.1 Java的一些简单新特性 3.1.1 静态导入 3.1.2 可变参数函数 3.1.3 增强版for循环 3.1.4 基本数据的拆、装箱操作(autoboxing和unboxing) 3.2 枚举 3.2.1 枚举的实现原理 3.2.2 枚举的简单应用 3.2.3 枚举的高级特性 3.3 反射 3.3.1 反射的基石——Class类 3.3.2 反射的基本应用 3.3.3 反射的高级应用 3.4 标注 3.4.1 标注的简单使用 3.4.2 JDK的内置标注 3.5 泛型 3.5.1 为什么要使用泛型 3.5.2 泛型的一些特性 3.5.3 泛型的通配符 3.6 类加载器 3.6.1 什么是类加载器 3.6.2 什么是类加载器的委派模型 3.6.3 编写一个自己的加载器 3.7 动态代理 3.7.1 什么是代理 3.7.2 动态代理基础类 3.7.3 InvocationHandler接口 3.7.4 动态代理类的设计模式 3.8 小结 第2篇 线程开发 第4章 学生并发接水(线Thread) 4.1 学生并发接水原理 4.1.1 项目结构框架分析 4.1.2 项目功能业务分析 4.2 不排队形式学生并发接水 4.2.1 水龙头类 4.2.2 学生类 4.2.3 测试类 4.3 学生并发接水的其他形式 4.3.1 “排队接水”水龙头类 4.3.2 “接完水后一起回教室”水龙头类 4.4 知识点扩展——线程的基础知识 4.4.1 为什么要使用线程 4.4.2 多线程程序的编写方式 4.5 小结 第5章 模拟做饭场景(线程的join()方法) 教学视频:7分钟5.1 做饭场景原理 5.1.1 项目结构框架分析 5.1.2 项目功能业务分析 5.2 纷乱的做饭场景 5.2.1 儿子的类 5.2.2 妈妈的类 5.2.3 做饭场景的类 5.2.4 修改后的妈妈类 5.3 知识点扩展——线程的状态 5.3.1 线程的创建状态 5.3.2 线程的暂停状态 5.3.3 线程的结束状态 5.4 小结 第6章 火车站售票系统(线程安全知识) 6.1 火车站售票系统原理 6.1.1 项目结构框架分析 6.1.2 项目功能业务分析 6.2 没有实现线程安全的火车票售票系统 6.2.1 火车票的类 6.2.2 售票台的类 6.2.3 实现线程安全的火车票售票系统 6.3 知识点扩展——线程的同步知识 6.3.1 为什么要使用同步机制 6.3.2 Synchronized的同步块 6.3.3 Synchronized的同步方法 6.3.4 死的问题 6.4 小结 第7章 生产者与消费者问题(线程通信知识) 7.1 生产者与消费者原理 7.1.1 项目结构框架分析 7.1.2 项目功能业务分析 7.2 无线程通信的生产者与消费者项目 7.2.1 生产者类 7.2.2 消费者类 7.2.3 储存库类 7.2.4 测试类 7.3 实现线程通信的生产者与消费者项目 7.3.1 生产者和消费者的类 7.3.2 储存库的类 7.4 知识点扩展——线程的通信知识 7.4.1 线程通信的基本知识 7.4.2 线程通信的具体实例 7.5 小结 第8章 关机工具(Timer类+系统命令) 8.1 关机工具原理 8.1.1 项目结构框架分析 8.1.2 项目功能业务分析 8.2 关机工具的实现过程 8.2.1 关机工具的类 8.2.2 关机工具的工具类 8.3 知识点扩展——关机工具项目涉及的知识 8.3.1 Timer和TimerTask类 8.3.2 shutdown命令 8.3.3 通过shutdown命令实现网络远程关机 8.4 小结 第3篇 GUI(图形用户界面)开发 第9章 典型的图形用户界面(各种组件) 9.1 Label和Button的用户界面 9.1.1 分析按钮和面板的用户界面 9.1.2 按钮和面板的用户界面 9.1.3 组件Button和Label的基本知识 9.2 复选框的用户界面 9.2.1 分析复选框的用户界面 9.2.2 按钮和面板的用户界面 9.2.3 组件Checkbox和CheckboxGroup的基本知识 9.3 下拉菜单和列表的用户界面 9.3.1 分析下拉菜单和列表的用户界面 9.3.2 下拉菜单和列表的用户界面 9.3.3 Choice和List组件的基本知识 9.4 输入的用户界面 9.4.1 分析输入的用户界面 9.4.2 输入的用户界面 9.4.3 TextField和TextArea组件的基本知识 9.5 滚动条的用户界面 9.5.1 分析滚动条的用户界面 9.5.2 滚动条的用户界面 9.5.3 滚动组件的基本知识 9.6 菜单的用户界面 9.6.1 分析菜单组件的用户界面 9.6.2 菜单的用户界面 9.6.3 菜单组件的基本知识 9.7 对话框的用户界面 9.7.1 分析对话框和文件对话框的用户界面 9.7.2 对话框的用户界面 9.7.3 Dialog和FileDialog组件的基本知识 9.8 小结 第10章 计算器(布局管理器) 10.1 计算器原理 10.1.1 项目结构框架分析 10.1.2 项目功能业务分析 10.2 计算器的实现过程 10.3 知识点扩展——事件机制的高级知识 10.3.1 为什么需要版面的配置 10.3.2 Java语言中的各种布局管理器 10.4 小结 第11章 秒表(事件+线程) 11.1 秒表原理 11.1.1 项目结构框架分析 11.1.2 项目功能业务分析 11.2 秒表的实现过程 11.2.1 秒表类 11.2.2 测试秒表的类 11.3 知识点扩展——事件机制的基础知识 11.3.1 事件处理机制 11.3.2 Window事件 11.3.3 Mouse事件 11.3.4 Key事件 11.3.5 其他底层事件 11.3.6 事件的高级编写方法 11.4 小结 第12章 捉迷藏游戏(事件) 12.1 捉迷藏游戏原理 12.1.1 项目结构框架分析 12.1.2 项目功能业务分析 12.2 捉迷藏游戏的实现过程 12.2.1 捉迷藏游戏项目的原理 12.2.2 自定义按钮类 12.2.3 测试的类 12.3 知识点扩展——事件机制的高级知识 12.3.1 事件多重应用 12.3.2 事件处理的详细过程 12.4 小结 第13章 鼠标绘直线(绘图+事件) 13.1 鼠标绘直线原理 13.1.1 项目结构框架分析 13.1.2 项目功能业务分析 13.2 鼠标绘直线的实现过程 13.2.1 直线的类 13.2.2 实现窗口类——通过paint()方法 13.2.3 实现窗口类——通过双缓冲技术 13.3 知识点扩展——画图的基础知识 13.3.1 画图的基础知识 13.3.2 各种类型对象的绘制 13.4 小结 第14章 指针时钟项目(Swing组件+时间算法) 14.1 指针时钟原理 14.1.1 项目结构框架分析 14.1.2 项目功能业务分析 14.2 指针时钟的实现过程 14.2.1 指针时钟的界面 14.2.2 绘制指针时钟的类 14.3 知识点扩展——从AWT到Swing的过渡 14.3.1 窗口类JFrame 14.3.2 按钮类JButton和面板类JLabel 14.3.3 单选按钮和复选框组件 14.3.4 选择框组件 14.3.5 输入框组件 14.4 小结 第15章 控制动画项目 (JSlider和Timer组件) 15.1 控制动画原理 15.1.1 项目结构框架分析 15.1.2 项目功能业务分析 15.2 控制动画的实现过程 15.2.1 控制动画的主界面 15.2.2 控制动画的逻辑 15.3 知识点扩展——JSlider和Timer组件的基础知识 15.3.1 使用JSlider组件创建无刻度的滑杆 15.3.2 使用JSlider组件创建带数字刻度的滑杆 15.3.3 使用JSlider组件创建带字符刻度的滑杆 15.3.4 JSlider组件的高级应用 15.3.5 Swing中的多线程 15.3.6 Timer组件的基础知识 15.3.7 Timer组件的应用 15.4 小结 第16章 记事本(对话框组件) 16.1 记事本原理 16.1.1 项目结构框架分析 16.1.2 项目功能业务分析 16.2 记事本的实现过程 16.2.1 实现记事本的界面 16.2.2 实现菜单功能 16.2.3 文件类型的过滤 16.3 记事本的实现过程——字体设置对话框 16.3.1 字体设置对话框——主界面 16.3.2 字体设置对话框——jPanel1组件界面 16.3.3 字体设置对话框——其他组件 16.4 小结 第17章 拼图游戏(GUI综合应用) 17.1 拼图游戏原理 17.1.1 项目结构框架分析 17.1.2 项目功能业务分析 17.1.3 拼图游戏项目的原理 17.2 拼图游戏的实现过程 17.2.1 实现移动功能的按钮类 17.2.2 主面板的类 17.2.3 主窗口的类 17.3 小结 第4篇 文件操作和访问 18.1 文件属性查看器原理 18.1.1 项目结构框架分析 18.1.2 项目功能业务分析 18.2 文件属性查看器项目 18.2.1 实现显示文件信息的自定义窗口 18.2.2 自定义窗口的显示 18.3 知识点扩展——文件的操作和访问 18.3.1 通过FileOp类实现文件创建和删除功能 18.3.2 通过FileDir类实现列举文件和目录的功能 18.3.3 File类提供的属性和方法 18.3.4 文件访问的基本概念 18.3.5 文件的基本访问方式——字节方式 18.3.6 文件的基本访问方式——字符方式 18.3.7 文件的高级访问方式 18.4 小结 第19章 文件内容查看器(GUI+文件访问) 19.1 文件内容查看器原理 19.1.1 项目结构框架分析 19.1.2 项目功能业务分析 19.2 文件内容查看器项目 19.2.1 设计项目的界面——文件内容查看器输入界面 19.2.2 “打开”菜单项的处理方法 19.2.3 单击列表选项的处理方法 19.3 知识点扩展——管道的访问 19.3.1 管道的访问——字节方式 19.3.2 管道的访问——字符方式 19.4 知识点扩展——内存的访问 19.4.1 内存的访问——字节方式 19.4.2 内存的访问——字符和字符串方式 19.5 小结 第20章 日记簿(GUI+文件访问和操作) 20.1 日记簿原理 20.1.1 项目结构框架分析 20.1.2 项目功能业务分析 20.2 日记簿项目 20.2.1 设计项目的界面——日记薄输入界面 20.2.2 “保存”按钮的事件处理 20.2.3 “查看日记”按钮的事件处理 20.2.4 设计项目的界面——日记列表界面 20.2.5 “查看”按钮的事件处理 20.2.6 “删除”按钮的事件处理 20.3 知识点扩展——过滤流的基础知识 20.3.1 过滤流的缓存(Buffering)类 20.3.2 过滤流实现字节和字符相互转换类 20.3.3 过滤流特定数据类型类 20.3.4 过滤流对象序列化类 20.3.5 过滤流打印类 20.4 小结 第21章 查找和替换项目(GUI+字符串处理) 21.1 查找和替换原理 21.1.1 项目结构框架分析 21.1.2 项目功能业务分析 21.2 查找和替换项目——利用AWT组件 21.2.1 设计项目的界面——查找和替换输入界面 21.2.2 各种按钮的事件处理 21.2.3 字符串处理的类 21.3 查找和替换项目——利用Swing组件 21.3.1 设计项目的界面——查找和替换输入界面 21.3.2 各种按钮的事件处理 21.4 小结 第5篇 Applet程序开发 第22章 图像轮显动画项目(显示图像+多线程) 22.1 图像轮显动画原理 22.1.1 项目结构框架分析 22.1.2 项目功能业务分析 22.2 图像轮显动画项目 22.3 知识点扩展——Applet程序的基础知识 22.3.1 Applet程序的执行过程 22.3.2 Applet程序的执行环境 22.3.3 Applet程序的输出 22.3.4 Applet程序的标记 22.3.5 参数的传递 22.3.6 Applet程序的相关方法 22.4 小结 第23章 Applet事件监听项目 (事件处理机制) 23.1 Applet事件监听原理 23.1.1 项目结构框架分析 23.1.2 项目功能业务分析 23.2 Applet事件监听项目 23.2.1 事件监听的类 23.2.2 承载事件监听的页面 23.3 知识点扩展——MyEclipse开发环境对Applet程序的支持 23.3.1 MyEclipse开发环境对Applet项目的支持 23.3.2 MyEclipse开发环境对JAR的支持 23.4 小结 第24章 动画播放项目(音频操作+多线程) 24.1 动画播放原理 24.1.1 项目结构框架分析 24.1.2 项目功能业务分析 24.2 动画播放项目 24.2.1 动画的类 24.2.2 控制动画的类 24.3 知识点扩展——Applet程序的高级知识 24.3.1 音频播放 24.3.2 Applet的上下文对象 24.4 小结 25.1 网络聊天室原理 25.1.1 项目结构框架分析 25.1.2 项目功能业务分析 25.2 网络聊天室的实现过程 25.3 知识点扩展——网络编程和UDP协议 25.3.1 网络编程涉及的基本概念 25.3.2 套接字(Socket)机制 25.3.3 UDP协议类 25.3.4 TCP协议类 25.3.5 TCP协议客户端类 25.4 小结 第26章 FTP服务器客户端 (FtpClient+I/O处理) 26.1 FTP服务器客户端原理 26.1.1 项目结构框架分析 26.1.2 项目功能业务分析 26.2 FTP服务器客户端的实现过程 26.2.1 FTP服务器操作的工具类 26.2.2 实现文件上传的类 26.2.3 实现文件下载的类 26.3 知识点扩展——FtpClient类的相关知识 26.3.1 实现FTP服务器相关操作类 26.3.2 相关JAR包导入问题 26.4 小结 第27章 Web服务器(HTTP协议) 27.1 Web服务器原理 27.1.1 项目结构框架分析 27.1.2 项目功能业务分析 27.2 Web服务器的实现过程 27.2.1 实现与浏览器通信的类 27.2.2 实现Web服务器的类 27.2.3 浏览器所请求的页面 27.3 知识点扩展——HTTP协议知识 27.3.1 HTTP协议原理 27.3.2 实现HTTP协议服务器的原理 27.4 小结 28.1 QQ聊天工具原理 28.1.1 项目结构框架分析 28.1.2 项目功能业务分析 28.2 QQ项目——对象模型的类 28.2.1 信息的类 28.2.2 “用户”的类 28.3 QQ项目——登录功能 28.3.1 QQ服务器界面的设计 28.3.2 QQ服务器后台程序 28.3.3 QQ客户端登录界面的设计 28.3.4 QQ客户端后台程序 28.3.5 成员列表窗口 28.4 QQ项目——聊天功能 28.4.1 服务器端的信息转发 28.4.2 客户端信息的发送和接收 28.4.3 客户端信息转发类 28.5 小结 第7篇 项目案例实战 第29章 人员信息管理项目 (接口设计模式+MySQL数据库) 29.1 人员信息管理原理 29.1.1 项目结构框架分析 29.1.2 项目功能业务分析 29.2 人员信息管理项目前期准备 29.2.1 设计数据库 29.2.2 数据库操作相关类 29.3 人员信息管理项目——DAO层 29.3.1 实现数据连接操作(DAO)的接口 29.3.2 实现数据连接操作(DAO)的实现类 29.3.3 实现数据连接操作(DAO)的代理类 29.3.4 实现数据连接操作(DAO)的工厂类 29.4 人员信息管理项目——服务层和表示层 29.4.1 人员信息管理项目的服务层 29.4.2 人员信息管理项目的表示层 29.4.3 工具类 29.5 人员信息管理项目——代理类测试 29.5.1 测试实现业务功能的各种方法 29.5.2 人员信息管理入口类 29.6 知识点扩展——设计模式的基础知识 29.6.1 工厂设计模式 29.6.2 代理设计模式 29.7 小结 第30章 中国象棋游戏(GUI+游戏规则算法) 30.1 象棋游戏原理 30.1.1 象棋游戏的基本规则 30.1.2 项目结构框架分析 30.1.3 项目功能业务分析 30.2 象棋游戏项目——象棋游戏的主类 30.2.1 实现象棋游戏的主界面 30.2.2 实现象棋游戏中添加棋子的功能 30.2.3 实现象棋游戏中棋子闪烁的功能 30.2.4 处理单击棋子事件 30.2.5 处理单击按钮事件 30.3 象棋游戏项目——规则的内部类 30.3.1 实现卒移动和吃的方法 30.3.2 实现炮、车移动和吃的方法 30.3.3 实现马移动和吃的方法 30.3.4 实现象移动和吃的方法 30.3.5 实现士移动和吃的方法 30.3.6 实现将移动和吃的方法 30.4 小结 第31章 俄罗斯方块游戏网络版(Swing+多线程+网络编程) 31.1 俄罗斯方块游戏项目原理 31.1.1 基本原理 31.1.2 项目结构框架分析 31.1.3 项目功能业务分析 31.2 俄罗斯方块游戏项目——初步设计涉及的对象 31.2.1 正方形类 31.2.2 俄罗斯方块类 31.2.3 俄罗斯方块游戏项目的TOP10分数对象 31.3 俄罗斯方块游戏项目——服务器端和客户端 31.3.1 表示出俄罗斯方块游戏项目的服务器端 31.3.2 表示出俄罗斯方块游戏项目的客户端 31.4 俄罗斯方块游戏项目——游戏主界面 31.4.1 俄罗斯方块游戏的主界面 31.4.2 俄罗斯方块游戏的事件处理类 31.4.3 俄罗斯方块游戏的状态工具栏 31.5 俄罗斯方块游戏项目——其他界面的设计 31.5.1 “关于”面板 31.5.2 连接对方面板 31.5.3 分数报告面板 31.5.4 设置级别面板 31.5.5 警告面板和对话框 31.5.6 游戏结束面板和对话框 31.6 小结 第32章 图书管理系统项目 (GUI+Oracle数据库) 32.1 图书管理系统原理 32.1.1 项目结构框架分析 32.1.2 项目功能业务分析 32.2 图书管理系统项目——图书的操作 32.2.1 实现添加图书功能的类 32.2.2 实现修改图书功能的类 32.2.3 实现浏览图书信息的类 32.2.4 实现删除图书信息的类 32.3 图书管理系统项目——用户的操作 32.3.1 实现添加用户功能的类 32.3.2 实现删除用户功能的类 32.3.3 实现修改用户功能的类 32.3.4 实现用户登录功能的类 32.3.5 实现用户列表功能的类 32.4 图书管理系统项目——出借图书的操作 32.4.1 出借图书操作的类 32.4.2 借书列表方法 32.4.3 修改出借图书信息方法 32.5 图书管理系统项目——归还图书的操作 32.5.1 归还图书类 32.5.2 修改归还图书信息类 32.6 图书管理系统项目——该项目的其他类 32.6.1 主窗口类 32.6.2 数据库操作 32.7 小结

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值