`
s103y
  • 浏览: 116734 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAVA笔记一

    博客分类:
  • java
阅读更多

一:在多态下,引用与对象可以是不同的类型,运行多态时,引用类型可以是实际对象类型的父类。参数和返回类型也可以多态。

二:抽象类不能被初始化,就是不能被new。抽象类除了被继承过之外,是没有用途,没有值,没有目的的。抽象类代表此类必须要被extend,抽象方法代表此方法一定要被覆盖。抽象的方法没有实体。如果你声明一个抽象的方法,就必须将类也标记为抽象的。你不能在非抽象类中拥有抽象的方法。

二:JAVA内存分配和管理

1、  JAVAJVM)内存模型(可见性和有序性)

可见性:多个线程之间是不能相互传递数据通信的,他们之间的沟通只能通过数据共享来进行。JAVA内存模型(JMM)规定了JVM有主内存,主内存是多个线程共享的。当new一个对象的时候,也是被分配在主内存中,每个线程都有自己的工作内存,工作内存存储了主内存的某些对象的副本,当然线程的工作内存大小是有限制的。当线程操作某个对象时,执行顺序如下:

(1)       从主存复制变量到当前工作内存(read and load);

(2)       执行代码,改变共享变量值(use and assign

(3)       用工作内存数据刷新主存相关内存(store and write)。

JVM规范定义了线程对主内存的操作指令:readloaduseassignstorewrite。当一个共享变量在多个线程的工作内存中都有副本时,如果一个线程修改了这个共享变量,那么其他线程应该能够看到这个被修改后的值,这就是多线程的可见性问题。

有序性:线程在引用变量时不能直接从主存中引用,如果线程工作内存中没有该变量,则会从主要中拷贝一个副本到工作内存中,这个过程为read-load,完成后线程会引用该副本。当同一线程再度引用该字段时,有可能重新从主从中获取该变量副本(read-load-use),也有可能直接引用原来的副本(use),也就是说readloaduse顺序可以由JVM实现系统决定。

线程不能直接为主存中的字段赋值,他会将值指定给工作内存中的变量副本(assign),完成后这个变量副本会同步到主存储区(store-write),至于何时同步过去,根据JVM实现系统决定,则会从主内存中将该字段赋值到工作内存中,这个过程为(read-load),完成后线程将会引用该变量副本,当同一线程多次重复对字段复制时,比如:

Forint i=0i<10;i++

{

a++;

}

线程有可能只对工作内存中的副本赋值,只到最后一次赋值才同步到主存储区,所以assignstorewrite顺序可以有JVM实现系统决定。假设有一个共享变量x,线程a执行x=x+1;从上面的描述中可以只到x=x+1;并不是一个原子操作,他的执行过程如下:

(1)       从主存中读取变量x副本到工作内存

(2)       x1

(3)       x1后的值写回主存。

如果另外一个线程b执行x=x-1;执行过程如下:

(1)       重主存中读取变量x副本到工作内存

(2)       x1

(3)       x1后的值写回主存

那么显然,最终x的值是不可靠的。假设现在为10;最终可能会得到多种结果。

Synchronized作为一种同步手段,解决java多线程的执行有序性和内存可见性。而volatile关键字解决多线程的内存可见性为题。

public class Account {

 

    private int balance;

 

    public Account(int balance) {

        this.balance = balance;

    }

 

    public int getBalance() {

        return balance;

    }

 

    public void add(int num) {

        balance = balance + num;

    }

 

    public void withdraw(int num) {

        balance = balance - num;

    }

 

    public static void main(String[] args) throws InterruptedException {

        Account account = new Account(1000);

        Thread a = new Thread(new AddThread(account, 20), "add");

        Thread b = new Thread(new WithdrawThread(account, 20), "withdraw");

        a.start();

        b.start();

        a.join();

        b.join();

        System.out.println(account.getBalance());

    }

 

    static class AddThread implements Runnable {

        Account account;

        int     amount;

 

        public AddThread(Account account, int amount) {

            this.account = account;

            this.amount = amount;

        }

 

        public void run() {

            for (int i = 0; i < 200000; i++) {

                account.add(amount);

            }

        }

    }

 

    static class WithdrawThread implements Runnable {

        Account account;

        int     amount;

 

        public WithdrawThread(Account account, int amount) {

            this.account = account;

            this.amount = amount;

        }

 

        public void run() {

            for (int i = 0; i < 100000; i++) {

                account.withdraw(amount);

            }

        }

    }

}

这段代码的执行结果会不一致。

2、  synchronized关键字

当一段代码会修改共享变量,这一段代码成为互斥区或者临界区,为了保证共享变量的正确性,synchronized标示了临界区。典型用例“

Synchronized(锁){

临界区代码

}

为了保证上面代码的安全,可以操作账号的方法如下:

public synchronized void add(int num) {

     balance = balance + num;

}

public synchronized void withdraw(int num) {

     balance = balance - num;

}

那么对于public synchronized void add(int num)这种情况,意味着什么呢?其实这种情况,锁就是这个方法所在的对象。同理,如果方法是public  static synchronized void add(int num),那么锁就是这个方法所在的class
       
理论上,每个对象都可以做为锁,但一个对象做为锁时,应该被多个线程共享,这样才显得有意义,在并发环境下,一个没有共享的对象作为锁是没有意义的。假如有这样的代码:

public class ThreadTest{

  public void test(){

     Object lock=new Object();

     synchronized (lock){

        //do something

     }

  }

}

lock变量作为一个锁存在根本没有意义,因为它根本不是共享对象,每个线程进来都会执行Object lock=new Object();每个线程都有自己的lock,根本不存在锁竞争。

每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个被线程被唤醒 (notify)后,才会进入到就绪队列,等待cpu的调度。当一开始线程a第一次执行account.add方法时,jvm会检查锁对象account 的就绪队列是否已经有线程在等待,如果有则表明account的锁已经被占用了,由于是第一次运行,account的就绪队列为空,所以线程a获得了锁,执行account.add方法。如果恰好在这个时候,线程b要执行account.withdraw方法,因为线程a已经获得了锁还没有释放,所以线程 b要进入account的就绪队列,等到得到锁后才可以执行。
一个线程执行临界区代码过程如下:
1
获得同步锁
2
清空工作内存
3
从主存拷贝变量副本到工作内存
4
对这些变量计算
5
将变量从工作内存写回到主存
6
释放锁
可见,synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。

三、Object对象

当你把对象装进Object中,他就变成Object对象,如果想转回原有对象,可以用以下方式:

Object o = a.get(index);

Dog d = (Dog)o;

如果不能确定他是Dog对象,可以用

If(o instanceof Dog){

Dog d = (Dog)o;

}

四、如何判断应该是设计类、子类、抽象类或接口

1、如果新的类无法对其他类通过IS-A测试时,就设计部继承其他类的类;

2、只有在需要某类的特殊化版本时,以覆盖或者增加新的方法来继承现有的类;

3、当你需要定义一群子类的模板,又不想让程序员初始化此模板是时,设计出抽象的类给他们使用;

4、如果想要定义出类可以扮演的角色,使用接口。

五、堆和栈

对象的生存空间是堆(heap),方法调用及变量的生存空间是栈(stack)。(实例对象是指声明在类中,而不是在方法中的变量,实例变量存在于对象所属的堆上)不管是实例变量还是局部变量,对象本身会放在堆中,对象引用变量与primitive主数据类型变量都会放在栈上。

对象的实例变量的值是存放于该对象中。

Lifescope的区别:

1、  只要变量的堆栈块还存在于堆栈上,局部变量就算活着。

2、  局部变量的范围只局限于声明他的方法之内,当此方法调用别的方法时,该变量还活着,但不在目前范围内,执行其他方法完毕返回时,范围也跟着回来。

六、静态方法不能调用非静态变量(实例变量),静态方法不能调用非静态方法;静态变量的值对所有实例来说都是相同的。

 

分享到:
评论

相关推荐

    JAVA笔记1.pdf

    JAVA笔记1.pdf

    java笔记java笔记

    java笔记java笔记java笔记java笔记java笔记java笔记java笔记

    java笔记 java笔记

    Java的设计理念是“一次编写,到处运行”,这意味着编写的Java程序可以在任何安装了Java虚拟机(JVM)的设备上运行。 #### 1.1 Java的特点 - **面向对象**:Java是一种纯粹的面向对象的语言,几乎所有的数据都是以...

    Java学习笔记学习笔记

    Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习...

    Java笔记桌面程序

    本项目名为"Java笔记桌面程序",它是由一个热衷于编程的开发者为解决其所在公司无法使用网络笔记客户端的问题而自创的。这个程序采用Java语言编写,充分体现了Java的跨平台特性,可以在多种操作系统上运行,包括...

    宋红康java笔记.rar

    【宋红康java笔记】是一份综合性的Java学习资料,由知名编程教育者宋红康编撰。这份压缩包文件包含了大量的Java编程知识点,旨在帮助初学者和有经验的开发者深入理解和掌握Java语言的核心概念与高级特性。以下是根据...

    大佬的java笔记

    专业的Java笔记可能会涉及这些内容,帮助学习者掌握Java的最新发展。 遗憾的是,由于【部分内容】部分不包含实际的笔记内容,无法进一步提供具体的编程示例和深入的解释。如果要学习Java,最好的方式是从学习Java的...

    非常好的java笔记适合初学者

    这份"非常好的java笔记"无疑是初学者踏入这个领域的宝贵资源。笔记由培训班的专业老师编写,内容详细且全面,旨在帮助初学者系统地学习和理解Java的基础知识。 首先,Java基础部分会涵盖变量、数据类型、运算符、...

    java读书笔记笔记笔记笔记笔记笔记

    【标题】"java读书笔记笔记笔记笔记笔记笔记" 暗示了这是一份关于Java编程语言的学习笔记,可能包含了作者在阅读Java相关书籍时所做的重要记录和理解。笔记通常涵盖了语言的基础概念、核心特性、类与对象、内存管理...

    狂神说Java笔记资料

    《狂神说Java笔记资料》是一份全面涵盖Java开发基础知识的文档集,旨在帮助学习者系统地掌握Java编程。这份笔记包含多个章节,每个章节都深入讲解了一个特定的主题,覆盖了从初学者到进阶开发者必备的知识点。 1. *...

    java笔记一

    【Java笔记一】是针对Java编程语言的一系列学习资料,主要涵盖了从基础到进阶的知识点,便于读者查阅和学习。这些压缩包文件可能是按照章节或者主题进行组织的,包括04、12、03、11、08、05、06、02、10和09共十个...

    java全套笔记 来自狂神说java笔录.zip

    【Java笔记内容概览】 1. **基础语法**:涵盖变量、数据类型、运算符、流程控制(条件语句、循环语句)、数组、字符串等基础知识。 2. **面向对象**:讲解类、对象、封装、继承、多态等核心概念,以及构造函数、...

    java学习笔记1

    Java学习笔记1 Java学习笔记1是学习Java过程中的笔记,主要记录了Eclipse开发环境中的快捷键使用、编辑功能、查找和调试等知识点。 Eclipse快捷键 Eclipse中有许多快捷键,掌握这些快捷键可以大大提高开发效率。...

    java超强笔记

    "Java超强笔记"正是一份专为新手准备的学习资源,它全面涵盖了从Java环境的搭建到软件设计的各种概念,旨在提供一个易读且系统的学习路径。 首先,笔记可能会从Java的起源和发展开始介绍,让你了解这门语言的历史...

    java笔记.zip

    2020-4-6 java笔记 ---内部类 2020-4-6 java笔记 ---异常 2020-4-6 java笔记 --多线程 2020-4-8 java笔记 String类 2020-4-9 java 比较器 2020-4-10 java笔记 枚举类 2020-4-10 java 注解(Annotation) 2020-4-11 ...

    尚硅谷JAVA基础笔记吐血整理

    “尚硅谷JAVA基础笔记”涵盖了Java语言的基础知识,包括语言概述、基本语法、面向对象概念、封装、继承和多态,以及一些关键概念如形参与实参、属性与局部变量、构造器、this关键字、包和MVC设计模式的使用。...

    java笔记整理,java课堂笔记

    全套java笔记整理,侧边栏目录结构方便查看,纯手工整理。达内笔记整理。 已整理成带侧边栏目录的网页结构,方便复习大纲和跳转查看。大部分都带有笔记代码。 (默认设置为深珊瑚蓝色调,不喜欢可以把配置文件里的...

    韩顺平编写的java学习笔记(全)

    1. **面向对象编程**:Java的核心概念之一,强调封装、继承、多态等特性。 2. **图形用户界面开发**:使用Swing或JavaFX等框架创建桌面应用。 3. **数据库编程**:连接数据库、执行SQL查询等操作。 4. **文件I/O流...

    java笔记本

    java笔记java笔记java笔记java笔记java笔记java笔记java笔记java笔记

    Java基础 学习笔记 Markdownr版

    1. 面向对象(OOP):Java的核心是面向对象编程,它将数据和操作数据的方法封装在一起,形成类。面向对象的三大特性——封装、继承和多态,在06面向对象(上)、07面向对象(中)和08面向对象(下)中进行了详细介绍...

Global site tag (gtag.js) - Google Analytics