Java 的一些学习的知识点

Java 总结归纳

部分定义:

标识符:
定义: Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符
技巧:凡是自己可以起名字的地方都叫标识符。

变量的一些知识点:

  1. 变量可以说内存中的一个存储区域,也叫做程序中最基本的存储单元

  2. 这个区域的数据可以在某一些范围内不断的变化。这就要涉及到一些变量类型的东西,不同的数据类型 数值的范围不用

  3. 注意的点:
    Java中每个变量必须先声明,后使用
    变量的作用域: 其定义所在的 {} 内

变量的分类-按声明的位置的不同
在方法体外,类体内声明的变量称为成员变量。
在方法体内部声明的变量称为局部变量。
在这里插入图片描述
注意: 局部变量除了形参外,需要显示初始化。
也就是说当局部变量在方法体或者代码块中 需要初始化。在这里插入图片描述

自动类型转换:
在这里插入图片描述
当把任何基本数据类型的值和String 进行高连接运算时,基本数据类型将自动转化为String类型
例子:
在这里插入图片描述
三元运算符:
在这里插入图片描述
关于Math 的知识点:

Math.floor() 表示向下取整,返回double类型 (floor—地板)
Math.ceil() 表示向上取整,返回double类型 (ceil—天花板)
Math.round() 四舍五入,返回int类型
Math.cos为计算弧度的余弦值
Math.toRadians函数讲角度转换为弧度

值传递机制:
在这里插入图片描述
Java Bean:
在这里插入图片描述
方法重写:
在这里插入图片描述
this 和super 的区别:
在这里插入图片描述
多态性的理解:

一句话理解就是:
在这里插入图片描述
在这里插入图片描述
多态性的一些特点:
在这里插入图片描述
instaance of 操作符
在这里插入图片描述

static 关键字:
修饰属性、方法、代码块、内部类

在这里插入图片描述
抽象类和抽象方法:
在这里插入图片描述
在这里插入图片描述
接口的部分知识点:
在这里插入图片描述
在这里插入图片描述
内部类:
在这里插入图片描述
成员内部类:
在这里插入图片描述
局部内部类:
声明在方法体内或者 代码块中:
在这里插入图片描述
如何使用:

  1. 只能声明在它的方法或者代码块中,先声明后使用。
  2. 但是它的对下昂可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或者父类的接口类型。

在这里插入图片描述
线程:

  • 多线程的创建: 方式一: 继承于Thread类

  • 1 创建一个继承于Thread类的子类

  • 2 重写Thread类的run() --> 将此线程执行官的操作声明在run()中

  • 3 创建Thread类的子类的对象

  • 4 通过此对象调用start(): 作用一:启动当前线程 作用二: 调用当前线程的run()

  • 创建多线程的方式二: 实现Runnable 接口

  • 1 创建一个实现了Runnable 接口的类

  • 2 实现类去实现Runnable中的抽象方法Run

  • 3 创建实现类的对象

  • 4 将此对象作为参数传递带Thread 类的构造器中,创建Thread类的对象

  • 5 通过Thread类的对象调用start()


  •  比较创建线程的两种方法:
    
  •  开发中优先选择: 实现Runnable接口的方式
    
  •  原因: 1 实现的方式没有类的单继承性的局限性
    
  •        2 实现的方式 更适合处理多线程有共享数据的情况
    

相同点: 都需要重写run(),都是将线程要执行的逻辑声明在run()中。
*


说明两个问题
问题一: 我们启动一个线程,必须点用start() 方法。不能调run()的方式启动线程
问题二:如果再启动一个,就必须重现创建thread子类的对象,调用该对象的start()方法

  • 测试Thread 中常用的方法:

  • 1 start():启动当前线程;调用当前线程的run()、

  • 2 run(): 通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中

  • 3 currentThread(): 静态方法, 返回执行当前代码的线程

  • 4 getName(): 获取当先线程的名字

  • 5 setName(): 设置当前线程的名字

  • 6 yield(): 释放当先cpu的执行权

  • 7 join(): 在线程A 中调用线程B 的 join(),此时线程A 就进 * 入阻塞状态,知道线程B 执行完成以后,

  •        线程A 才结束阻塞状态
    
  • 8 stop(): 已过时 在执行此方法时,强制结束当前线程

  • 9 sleep():

  • 10 isAlive(): 判断是否存活

  • 线程的优先级

  • 1

  • MAX_PRIORITY : 10

  • MIN_PRIORITY: 1

  • NORM_PRIORITY: 5

  • 2 如何获取和设置当前线程的优先级

  •  getPriority():获取线程的优先级
    
  •  setPriority(): 设置线程的优先级
    
  •  说明: 高优先级的线程要抢占cpu的优先级,但是只是从概率上来说
    
  •        高优先级的线程高概率的情况下被执行。并不意味着只有高优先级的线程执行完以后,低优先级才执行
    

线程的通信: wait()/ notify() / notifyAll()

线程的生命周期
在这里插入图片描述

Java中通过同步机制解决线程的安全问题:
方式一:
同步代码块:
synchronized 关键字
synchronized(同步监视器){
//需要被同步的代码
}
说明: 1. 操作共享数据的代码,即为需要被同步的代码
2. 共享数据: 多个线程共同操作的变量。
3. 同步监视器,俗称: 锁。 任何一个类的对象都可以
充当锁。
要求: 多个线程必须共用同一把锁。

继承中的实现synchronized

class Window extends Thread{

    private static int ticket = 100;
    private static Object obj = new Object();

    @Override
    public void run() {
        while (true){
            synchronized (this){//synchronized(obj){
                if (ticket > 0) {
                    System.out.println(getName() + ": 票号为: " + ticket );
                    ticket--;
                }else {
                    break;
                }
            }
        }
    }
}

public class WindowTest {
    public static void main(String[] args) {
        Window window1 = new Window();
        Window window2 = new Window();
        Window window3 = new Window();

        window1.setName("窗口1: ");
        window2.setName("窗口2: ");
        window3.setName("窗口3: ");

        window1.start();
        window2.start();
        window3.start();

    }
}

接口Runnable实现synchronzed

class Window1 implements Runnable{
    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if (ticket > 0) {

                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ": 票号为: " + ticket );
                    ticket--;
                }else {
                    break;
                }
            }

        }
    }
}

public class WindowTest1 {
    public static void main(String[] args) {
        Window1 window = new Window1();


        Thread t1 = new Thread(window);
        Thread t2 = new Thread(window);
        Thread t3 = new Thread(window);

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

        t1.start();
        t2.start();
        t3.start();

    }
}

方式二:
同步方法:
如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明为同步的。

继承中的实现synchronized


/**
 *  同步方法仍然涉及到了同步监视器,只是不需要我们显示声明
 *
 *  注意: 非静态的同步方法,同步监视器是:this
 *        静态的同步方法,同步监视器是: 当前类本省
 *
 */

class Window3 extends Thread{

    private static int ticket = 100;


    @Override
    public void run() {
        while (true){
            show();
        }
    }

    private static synchronized void show(){//同步监视器是 当前类本身 window3.class
//    private synchronized void show(){//同步监视器: t1,t2,t3  此方法不能实现同一个锁,所以要用static
        if (ticket > 0) {
            System.out.println(Thread.currentThread().getName() + ": 票号为: " + ticket);
            ticket--;
        }
    }
}

public class WindowTest3 {
    public static void main(String[] args) {
        Window3 window1 = new Window3();
        Window3 window2 = new Window3();
        Window3 window3 = new Window3();

        window1.setName("窗口1: ");
        window2.setName("窗口2: ");
        window3.setName("窗口3: ");

        window1.start();
        window2.start();
        window3.start();

    }
}

接口Runnable实现synchronzed

class Window2 implements Runnable{
    private int ticket = 100;
    @Override
    public void run() {
        while (true) {
            show();
        }
}
    public synchronized void show() { // 同步监视器: this
        if (ticket > 0) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        System.out.println(Thread.currentThread().getName() + ": 票号为: " + ticket);
        ticket--;
        }
    }
}

public class WindowTest2 {
    public static void main(String[] args) {
        Window2 window = new Window2();


        Thread t1 = new Thread(window);
        Thread t2 = new Thread(window);
        Thread t3 = new Thread(window);

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

        t1.start();
        t2.start();
        t3.start();

    }
}
  1. 同步的方式,解决了线程的安全问题 – 好处
    操作同步代码是,只能有一个线程参与,其它线程等待。相当于是一个但线程的操作。

使用同步机制将单例模式中的懒汉式改写为线程安全的

public class BankTest {
}

class Bank{
    private Bank(){}

    private static Bank instance = null;


    public static Bank getInstance(){
        //方式一: 效率稍差
//        synchronized (Bank.class) {
            if (instance == null) {
                instance = new Bank();
            }
            return instance;
        }

        //方式二: 稍微优化了一下代码,如何第一个进来的已经new 了对象,则后面的就不用再进入同步代码块内部了
        if (instance == null) {
            synchronized (Bank.class) {
                if (instance == null) {
                    instance = new Bank();
                }
            }
        }
        return instance;
    }
}

线程的死锁问题:

在这里插入图片描述
解决线程的安全问题:Lock

package java1;

import java.util.concurrent.locks.ReentrantLock;

/**
 * 解决线程安全的方式三: Lock锁
 *
 * 
 */

class Window implements Runnable{
    private int ticket = 100;
    //实例化ReentrantLock
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true){
            try{
                //调用锁定Lock()的方法
                lock.lock();

                if (ticket > 0) {

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + " 票号为:" + ticket);
                    ticket--;
                }else {
                    break;
                }
            }finally {
                //调用解锁方法
                lock.unlock();
            }

        }
    }
}

public class LockTest {
    public static void main(String[] args) {
        Window window = new Window();

        Thread t1 = new Thread(window);
        Thread t2 = new Thread(window);
        Thread t3 = new Thread(window);

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

        t1.start();
        t2.start();
        t3.start();
    }
}

知识点: synchronized 与 Lock 异同
同: 解决线程的安全问题
不同点:Lock 有点像手动锁定和解锁,较为灵活
synchronized 机制属于自动的锁定和解锁,在执行完相应的
同步代码块以后,自动的释放同步监视器

线程同步的应用:

package Account;

/**
 *  用线程的安全性 去解决现实中的小问题
 */

class Account{
    private double balance;

    public Account(double balance){
        this.balance = balance;
    }

    //存钱
    public synchronized void deposit(double amt){
        if (amt > 0) {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            balance +=amt;
            System.out.println(Thread.currentThread().getName() + "存钱:" + amt + " 余额:" + balance);
        }
    }
}

class Customer extends Thread{
    private Account acct;

    public Customer(Account acct){
        this.acct = acct;
    }

    @Override
    public void run(){
        for (int i = 0; i < 3; i++) {
            acct.deposit(1000);
        }
    }
}

public class AccountTest {
    public static void main(String[] args) {
        Account account = new Account(0);
        Customer customer1 = new Customer(account);
        Customer customer2 = new Customer(account);

        customer1.setName("甲");
        customer2.setName("乙");

        customer1.start();
        customer2.start();

    }
}

wait() notify() notifyAll() 三个方法的特性:

package ThreadCommunication;

/**
 *  线程的通信
 *  两个线程打印1-100。线程1和线程2交替打印
 *
 *  涉及到的三个方法:
 *  wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器
 *  notify(): 一旦执行此方法,就会唤醒被wait()的一个线程,如果多个线程wait,则按照优先级高的被唤醒
 *  notifyAll(): 一旦执行此方法,就会唤醒所有的wait线程
 *
 *  说明:
 *
 *  1 wait(),notify(),notifyAll三个方法必须使用在同步代码块或同步方法中
 *  2 wait(),notify(),notifyAll 三个方法的调用者必须是同步代码块或同步方法中的同步监视器
 *  3 wait(),notify(),notifyAll 三个方法 是定义在java.lang.Object类中的
 */

class Number implements Runnable{

    private int number = 1;


    @Override
    public void run() {

        while (true){
            //wait()和notify()方法的调用必须具有内置锁 synchronized(this) 的代码块内或同步方法才能调用,否则就会报该错误。
            synchronized (this) {

                notify();

                if (number<=100) {
                    System.out.println(Thread.currentThread().getName() + ": " + number);
                    number++;

                    try {
                        //使得该线程阻塞
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }else {
                    break;
                }
            }
        }
    }
}

public class CommunicationTest {
    public static void main(String[] args) {

        Number number = new Number();

        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("线程1: ");
        t2.setName("线程2: ");

        t1.start();
        t2.start();


    }
}

例题:sleep() 和 wait() 的异同

相同点: 都可以使当前的线程进入阻塞状态

不同点:

  1. 两个方法声明的位置不同,Thread类中声明sleep(), Object类中声明wait().
  2. 调用的要求不同,sleep() 可以在任何需要的场景下调用,wait() 必须是在同步代码或同步方法中。
  3. 关于释放释放同步监视器,如果两个方法都使用在了同步代码块或同步方法中,sleep() 不会释放同步监视器,wait()会释放同步监视器。

创建线程的方式三: Callable接口

在这里插入图片描述

package ThreadNew;

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

/**
 *  创建线程的方式三: 实现callable接口。
 *  特点:
 *  1 Call方法有返回值
 *  2 能抛出异常
 *  3 支持泛性
 */

//1 创建一个实现Callable的实现类
class NumberThread implements Callable{
    // 2 实现call方法,将此线程需要执行的操作声明在call方法中
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
                sum += i;
            }
        }
        return sum;

    }
}
public class CallableUsing {
    public static void main(String[] args) {
        // 3 创建Callable 接口实现类的对象
        NumberThread numberThread = new NumberThread();
        // 4 将此callable 接口实现类的对象作为参数传递到FutureTask构造器中,创建FutureTask的对象
        FutureTask futureTask = new FutureTask(numberThread);
        // 5 将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start方法
        new Thread(futureTask).start();

        try {
            // 6 获取Callable中call方法的返回值
            //get 方法的返回值即为FutureTask构造器Callable实现类重写的call()的返回值
            Object sum = futureTask.get();
            System.out.println(sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

实现线程的方式四: 使用线程池

package ThreadNew;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *
 *  实现线程的方法四:线程池
 *  
 */

class NumberThread1 implements Runnable{

    @Override
    public void run() {
        for (int i = 1; i <= 100 ; i++) {
            if (i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + i);
            }
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {
        // 1 提供指定线程数量的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 2 执行指定线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象
        executorService.execute(new NumberThread1()); //适用于Runnable
//        executorService.submit();  //适用于Callable
        //关闭线程池
        executorService.shutdown();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值