java第一阶段-JavaSE-Day22多线程

一、对象序列化

(一)对象序列化流使用

1、概述

将对象从内存中写到文件中

对象序列化流:

ObjectOutputStream 对象输出流,他也是一个包装流,可以把一个普通字节输出流包装为能写对象能力的流

将java对象的原始数据类型和内容写入OutputStream

对象反序列化流:

ObjectInputStream读取对象,对象输入流,它也是一个包装流,可以把一个普通字节输入流,包装为能读取对象能力的流

 

package com.offcn.demo02;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class Demo01 {
    public static void main(String[] args) throws Exception{
        String s = "我爱学习java";
        FileOutputStream fos = new FileOutputStream("Day22/b/4.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(s);
        oos.close();
        fos.close();
    }
}

2、自定义对象序列化

案例:创建一个Student类,提供一些属性,再创建一个Student对象,把这个学生对象写出文件中

package com.offcn.demo02;

import java.io.Serializable;

public class Person implements Serializable {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 

package com.offcn.demo02;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Demo02 {
    public static void main(String[] args) throws IOException {
        Person p = new Person("tom",19);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Day22/b/person.txt"));
        oos.writeObject(p);
        oos.close();
    }
}

注意事项:

①一个对象要想被序列化,该对象所属的类必须实现Serializable接口

②Serializable是一个标记接口,实现该接口,不需要重写任何方法

3、对象反序列化流使用

对象反序列化介绍:

就是将持久化保存的对象,按照字节顺序进行读取

ObjectInputStream:

ObjectInputStream反序列化前先使用ObjectInputStream编写的原始数据和对象

 

package com.offcn.demo03;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class Demo01 {
    public static void main(String[] args) throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Day22/b/4.txt"));
        Object o = ois.readObject();
        System.out.println(o);
        ois.close();
    }
}

 

package com.offcn.demo03;

import com.offcn.demo02.Person;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class Demo02 {
    public static void main(String[] args) throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Day22/b/person.txt"));
        Person p = (Person)ois.readObject();
        ois.close();
        System.out.println(p.getName());
        System.out.println(p.getAge());
        System.out.println(p);
    }
}

二、Properties类【必须掌握的知识点】

1、Properties

介绍:

表示一个持久的属性集

属性集:属性名称和属性值的对应关系,其实还是个双列集合

持久的:可以保存到流中,也可以从流中取出,可以很方便和文件进行交互

是一个Map体系的集合类,是Hashtable的子类

属性列表中的每个键及其对应的值都是一个字符串,因此不需要写泛型

2、Properties特有方法

 

package com.offcn.demo04;

import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        Properties p = new Properties();
        p.setProperty("name","tom");
        p.setProperty("age","18");
        p.setProperty("gender","男");

        System.out.println(p.getProperty("name"));
        Set<String> strings = p.stringPropertyNames();
        for (String string : strings) {
            System.out.println(string+"----"+p.getProperty(string));
        }
    }
}

3、Properties和IO流相结合的方法

 

Properties操作的文件是有要求的,必须是.properties文件

package com.offcn.demo04;

import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        Properties p = new Properties();
        p.setProperty("name","tom");
        p.setProperty("age","18");
        p.setProperty("gender","男");

        System.out.println(p.getProperty("name"));
        Set<String> strings = p.stringPropertyNames();
        for (String string : strings) {
            System.out.println(string+"----"+p.getProperty(string));
        }
        p.store(new FileWriter("Day22/b/per.properties"),null);
    }
}

注意事项:

①使用prop修改了属性值后,文件中的属性值不会发生变化,因为prop值修改了内存中的对象数据,没有同步到文件中,必须调用store方法之后,才能将变化同步到文件

②调用store方法时,一般需要指定更新属性的原因,即第二个参数comments,如果没有注释,可以传入null;如果有注释,必须是纯英文的。

三、线程相关概念

(一)进程和线程的区别

1、进程:

是指一个内存中运行的应用程序(已经在内存中运行的程序). 一个进程都有一个独立的

内存空间,一个电脑(手机)可以同时运行多个进程;进程也是程序的一次执行过程,是系统

运行程序的基本单位;

2、线程:

线程是进程中的一个执行单元(线程是依赖于进程的),负责当前进程中程序的执行,

一个进程中至少有一个线程(单线程程序)。一个进程中是可以有多个线程的,这个应用程序

也可以称之为多线程程序。

线程本身不具备申请操作系统资源能力,他必须依赖进程,才能使用操作系统的资源

 

 

(二)并行和并发

并行:指两个或多个事件在同一时间发生(同时发生,同时处理,执行者不是一个)

并发:指两个或多个事件在同一个时间段内发生(交替的发生 执行者是一个)

(三)java实现多线程的三种方式

1、继承Thead类

Thread就是一个线程类,里面定义所有和线程相关的功能,只有这个类才能开启的人物,才能被cpu单独去执行

方法:

 

实现步骤:

定义一个类MyThread继承Thread类

在MyThread类中重写run()方法,添加自己的任务

创建MyThread类的对象

启动线程

注意事项:千万不要使用线程对象调用run方法

package com.offcn.demo05;

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("我爱java...."+i);
            System.out.println(getName());
        }
    }
}
package com.offcn.demo05;

public class Demo01 {
    public static void main(String[] args) {
        MyThread m = new MyThread();
        m.start();
        for (int i = 0; i <1000 ; i++) {
            System.out.println("java使我快乐..."+i);
        }
    }
}

 

 

2、实现Runnable接口

里面只有一个抽象方法 一个抽象方法:run,用来定义线程中要执行的任务内容。这个Runnable仅仅就是一个任务而已,需要把任务绑定到线程中

方法:

 

解释:

Thread的构造方法创建对象的时候传入了Runnable接口的对象 ,Runnable接口对象重写run方法相当于

指定线程任务,创建线程的时候绑定了该线程对象要干的任务

Runnable的对象称之为:线程任务对象 不是线程对象 必须要交给Thread线程对象

通过Thread的构造方法, 就可以把任务对象Runnable,绑定到Thread对象中, 将来执行start方法,就会 自动执行 Runnable实现类对象中的run里面的内容.

注意:之所以提供第二种实现线程方式,是为了提供任务的复用性,解开了任务和线程之间的耦合性

实现步骤:

定义一个类MyRunnable实现Runnable接口

在MyRunnable类中重写run()方法

创建MyRunnable类的对象

创建Thread类的对象,把MyRunnable对象作为构造方法的参数

启动线程

package com.offcn.demo06;

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("我是一个任务.....");
        }
    }
}

 

package com.offcn.demo06;

public class Demo01 {
    public static void main(String[] args) {
        MyRunnable mr = new MyRunnable();
        Thread t = new Thread(mr);
        Thread t2 = new Thread(mr);
        t2.start();
        t.start();
        for (int i = 0; i <1000 ; i++) {
            System.out.println("我是主线程.....");
        }
    }
}

 

3、实现Callable接口

方法:

 

FutureTask实现了RunnableFuture接口,而RunnableFuture是Runnable接口子接口,所以FutureTask对

象就可以看做一个Runnable接口实现类对象使用, 可以通过Thread类的Thread(Runnable target)或

Thread(Runnable target String name)构造方法,把FutureTask对象绑定到线程对象中.

通过观察FutrueTask构造方法, 发现有一个构造中可以接受一个Callable类型的参数. Callable也是一个任务接口,里面用来定义线程中要执行任务,只不过Callable中任务在执行完成之后会给线程调用者一个反馈.因为Callable中的call会在任务执行完给提供反馈

实现步骤

定义一个类MyCallable实现Callable接口

在MyCallable类中重写call()方法 这就是线程任务方法.这个方法有返回值.

创建MyCallable类的对象

创建FutureTask的实现类FutureTask对象,把MyCallable对象作为构造方法的参数

创建Thread类的对象,把FutureTask对象作为构造方法的参数

启动线程

再调用get方法,就可以获取线程结束之后的结果。 call方法什么时候执行完,get才会执行.就可以拿到任务执行完后结果.

package com.offcn.demo07;

import java.util.concurrent.Callable;

public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        for (int i = 0; i <1000 ; i++) {
            System.out.println("线程任务...."+i);
        }
        return "任务结束";
    }
}
package com.offcn.demo07;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class Demo01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable mc = new MyCallable();
        FutureTask<String> ft = new FutureTask<>(mc);
        Thread t = new Thread(ft);
        t.start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程...");
        }
        System.out.println(ft.get());
    }
}

 

四、线程Thread类常用方法

(一)线程API之线程名称

 

package com.offcn.demo08;

import com.offcn.demo05.MyThread;

public class Demo01 {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread();
        System.out.println(mt1.getName());
        MyThread mt2 = new MyThread();
        System.out.println(mt2.getName());
        Thread t = new Thread();
        System.out.println(t.getName());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 全国v3.0版javase加强第一阶段-第2套卷主要是指在javase基础上进行加强学习和应用。在这套卷中,学习者需要掌握更高级的Java编程知识和技巧。 首先,学习者需要对Java语言有扎实的掌握。他们应该熟练掌握Java的基本语法、数据类型、流程控制、面向对象等基础知识。在此基础上,他们还需要深入了解Java的高级特性,如多态、继承、接口等,并能够灵活运用这些知识解决实际问题。 此外,学习者还需要学习和掌握Java的核心类库。他们应该了解Java集合框架、IO流、多线程等核心类库的使用方法和原理,并能够利用这些类库进行开发和优化。 在加强第一阶段的学习中,学习者还应该注重实践。他们应该通过编写各种类型的Java程序来加深对知识的理解和掌握。这些程序可以是简单的练习题,也可以是实际的应用开发项目。 通过学习全国v3.0版javase加强第一阶段-第2套卷,学习者能够进一步提升自己的Java编程能力。他们将能够更加熟练地运用Java语言和核心类库进行开发,并能够解决更复杂、更实际的编程问题。这将为他们今后的学习和工作打下坚实的基础。 ### 回答2: 全国V3.0) JavaSE加强第一阶段-第2套卷是一套用于加强JavaSE知识的教材。JavaSEJava平台标准版的缩写,是Java语言的基础,涵盖了Java语言的基本语法、面向对象编程、异常处理、多线程、集合框架等内容。 这套教材的目的是在第一阶段的基础上,进一步加强学生对JavaSE的理解和应用能力。它通过一系列的教学案例,让学生掌握更深入的编程技巧和方法。对于想要进一步提升Java编程能力的学生来说,这套教材是一个很好的选择。 教材中的内容包括Java中的异常处理、文件操作、网络编程、GUI界面设计等多个方面。 这些内容都是Java编程中非常重要的知识点,掌握了这些知识,学生可以更加灵活地运用Java语言来解决实际问题。 教材的设计符合教育教学规律,注重理论与实践相结合,通过实际的编程案例,帮助学生巩固理论知识,并且锻炼解决实际问题的能力。 总之,全国V3.0) JavaSE加强第一阶段-第2套卷是一套旨在加强学生对JavaSE知识理解和应用能力的教材。它涵盖了JavaSE的核心内容,通过实例教学帮助学生锻炼编程能力。对于想要进一步提升Java编程水平的学生来说,这套教材是一个非常实用和有效的学习工具。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

皇正经

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

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

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

打赏作者

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

抵扣说明:

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

余额充值