作业解析

  1. 利用白富美接口案例,土豪征婚使用匿名内部类对象实现。

     interface White{
    public void white();
    } interface Rich{
    public void rich();
    } interface Beauty{
    public void beauty();
    } interface WRB extends White, Rich, Beauty{
    } class TuHao{
    public void getMarry(WRB wrb){
    wrb.white();
    wrb.rich();
    wrb.beauty();
    }
    } class Demo{
    public static void main(String[] args){
    TuHao wsc = new TuHao();
    wsc.getMarry(new WRB(){
    public void white(){
    System.out.println("white");
    }
    public void rich(){
    System.out.println("rich");
    }
    public void beauty(){
    System.out.println("beauty");
    }
    });
    }
    }
  2. 定义三角形类Trianle,里面包含三个int类型属性,分别表示三条边的长度,

    构造三角形对象时,任意两边之和是否大于第三边,如若不成立,抛出自定义异常。

     class Triangle{
    private int a;
    private int b;
    private int c;
    public Triangle(int a, int b, int c){
    try{
    if(a>=b+c || b>=a+c || c>=a+b){
    throw new TriangleLengthException("Invalid Length");
    }
    else{
    this.a = a;
    this.b = b;
    this.c = c;
    }
    }
    catch(TriangleLengthException e){
    e.printStackTrace();
    }
    }
    } class TriangleLengthException extends Exception{
    String exceptionInfo;
    public TriangleLengthException(String info){
    exceptionInfo = info;
    } public void printStackTrace(){
    System.out.println(exceptionInfo);
    }
    } class TriExceptionDemo{
    public static void main(String[] args){
    Triangle t1 = new Triangle(2,3,4);
    Triangle t2 = new Triangle(2,2,4);
    Triangle t3 = new Triangle(2,7,4);
    }
    }
  3. Person类中增加birthday属性,对setBirthday(int ,int , int )方法进行异常处理,

    要求年有效、月有效、日有效、年月日指定的具体日期有效,对不同情况分别抛出不同的异常。

    year:>1970, month:1-12, day:1-31

     class Person{
    private int year;
    private int month;
    private int day;
    public void setBirthday(int year, int month, int day){
    try{
    if(year<1970){
    throw new YearException("Invalid Year");
    }
    else{
    if(month<1 || month > 12){
    throw new MonthException("Invalid Month");
    }
    else{
    if(day<1 || day>31){
    throw new DayException("Invalid Day");
    }
    else{
    switch(month){
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
    break;
    case 2:
    if((year%400==0) || (year%4==0 && year%100!=0)){
    if(day>29){
    throw new DateException("Invalid Date");
    }
    }
    else{
    if(day>28){
    throw new DateException("Invalid Date");
    }
    }
    case 4:
    case 6:
    case 9:
    case 11:
    if(day==31){
    throw new DateException("Invalid Date");
    }
    }
    }
    }
    }
    }
    catch(Exception e){
    e.printStackTrace();
    }
    }
    } class YearException extends Exception{
    String exceptionInfo;
    public YearException(String info){
    exceptionInfo = info;
    }
    public void printStackTrace(){
    System.out.println(exceptionInfo);
    }
    } class MonthException extends Exception{
    String exceptionInfo;
    public MonthException(String info){
    exceptionInfo = info;
    }
    public void printStackTrace(){
    System.out.println(exceptionInfo);
    }
    } class DayException extends Exception{
    String exceptionInfo;
    public DayException(String info){
    exceptionInfo = info;
    }
    public void printStackTrace(){
    System.out.println(exceptionInfo);
    }
    } class DateException extends Exception{
    String exceptionInfo;
    public DateException(String info){
    exceptionInfo = info;
    }
    public void printStackTrace(){
    System.out.println(exceptionInfo);
    }
    } class BirthdayExceptionDemo{
    public static void main(String[] args){
    Person p1 = new Person();
    p1.setBirthday(12,1,22);
    p1.setBirthday(1970,13,22);
    p1.setBirthday(2000,1,32);
    p1.setBirthday(2000,2,28);
    p1.setBirthday(2000,2,29);
    p1.setBirthday(2016,2,30);
    p1.setBirthday(2100,2,29);
    }
    }
  4. 将类定义到指定的包下。com.xkzhai.jar,编译之后,打成jar文件。

    • 编写源文件jarDemo.java

        package com.xkzhai.jar;
      class Person{
      private String name;
      private String sex;
      public void run(){
      System.out.println("run");
      }
      } class jarDemo{
      public static void main(String[] args){
      Person p1 = new Person();
      p1.run();
      }
      }
    • 编译到指定的位置

        javac -d classes2 jarDemo.java
      
      
    • 归档

        jar cvf test.jar -C classes2/ .
      jar cvfe test2.jar com.xkzhai.jar.jarDemo -C classes2/ . //在清单文件中增加入口点
    • 运行程序

        java -cp classes2 com.xkzhai.jar.jarDemo
      java -cp test.jar com.xkzhai.jar.jarDemo
      java -jar test2.jar//定义好入口点的jar包
  5. 相互之间使用jar包,放置cp下,对class进行重用

    • 编写第一个java程序Person.java

        package com.xkzhai.jar1;
      //不同包下的类重用,需定义为public
      public class Person{
      private String name;
      private String sex;
      private int age;
      public void setAge(int age){
      this.age = age;
      }
      public int getAge(){
      return age;
      }
      }
    • 编译上述文件,放置到classes3文件夹下

        javac -d classes3 Person.java
      
      
    • 将类文件打包归档为jar1.jar,放置在lib文件夹下

        jar cvf jar1.jar -C classes3/ .
      
      
    • 重用Person类,编写第二个java程序jarDemo2.java,放置在src文件夹下

        package cn.xkzhai;
      import com.xkzhai.jar1.Person;
      class Student extends Person{
      private String ID;
      } class jarDemo2{
      public static void main(String[] args){
      Student s1 = new Student();
      s1.setAge(20);
      System.out.println(s1.getAge());
      }
      }
    • 编译jarDemo2.java,生成的类文件放置在classes中

        javac -cp lib/jar1.jar -d classes src/jarDemo2.java
      
      
    • 执行

        java -cp lib/jar1.jar;classes cn.xkzhai.jarDemo2
      
      
  6. 设计程序,考查修饰符。public -> protected -> default -> private(选做题)

  7. 编写ArrayTool,把冒泡排序,选择排序,二分法查找等打成jar包。

    • 编写java源文件ArrayTool3.java

        package com.xkzhai.array;
      
        class ArrayTool3{
      int[] arrayData; public ArrayTool3(){
      } public ArrayTool3(int[] arrayData){
      this.arrayData = arrayData;
      } //1. 打印数组元素
      public void outArray(){
      for(int i: arrayData){
      System.out.println(i);
      }
      } //2. 冒泡排序
      // 5 4 3 2 1
      // 4 3 2 1 5
      // 3 2 1 4 5
      // 2 1 3 4 5
      // 1 2 3 4 5
      public void bubbleSort(){
      for(int i = arrayData.length-1;i>0;i--){
      for(int j=0;j<i;j++){
      if(arrayData[j]>=arrayData[j+1]){
      int tmp = arrayData[j];
      arrayData[j] = arrayData[j+1];
      arrayData[j+1] = tmp;
      }
      }
      }
      } //3. 选择排序
      //5 4 3 2 1
      //1 5 4 3 2
      //1 2 5 4 3
      //1 2 3 5 4
      //1 2 3 4 5
      public void selectSort(){
      for(int i=0;i<arrayData.length-1;i++){
      for(int j=i;j<=arrayData.length-1;j++){
      if(arrayData[j]<=arrayData[i]){
      int tmp = arrayData[j];
      arrayData[j] = arrayData[i];
      arrayData[i] = tmp;
      }
      }
      }
      } //4. 选择排序
      public int halfFind(int c){
      int min = 0;
      int max = arrayData.length-1;
      int index = 0; while(min<=max){
      index = (min+max)/2;
      if(arrayData[index]>c){
      max = index-1;
      }
      else if(arrayData[index]<c){
      min = index+1;
      }
      else{
      return index;
      }
      }
      return -1;
      }
      } class ArrayDemo{
      public static void main(String[] args){
      ArrayTool3 arr = new ArrayTool3(new int[]{1,3,2,20,12});
      arr.outArray();
      arr.bubbleSort();
      arr.outArray(); ArrayTool3 arr2 = new ArrayTool3(new int[]{1,3,2,20,12,23,21,19});
      arr2.outArray();
      arr2.selectSort();
      arr2.outArray();
      System.out.println(arr2.halfFind(-1));
      System.out.println(arr2.halfFind(12));
      }
      }
    • 编译,打包

        javac -d classes4 ArrayTool3.java
      //java -cp classes4 com.xkzhai.array.ArrayDemo
      jar cvf ArrayTool.jar -C classes4/ .
  8. 预习多线程。

进程

  1. 运行时(runtime)的应用程序

  2. 进程之间的内存不是共享(独占)

  3. 进程间通信使用的socket(套接字)

    进程之间内存是隔离的。内存不共享。

多线程

  1. 程序(进程)执行过程中,并发执行的代码段

  2. 线程之间共享内存

  3. 创建灵活响应的桌面程序

  4. 每个运行着的线程对应一个stack(方法栈)

  5. 应用程序至少有一个线程(主线程)

java.lang.Thread

  1. Thread.yield()方法:让当前线程让出CPU抢占权,具有谦逊之意,瞬时的动作

  2. Thread.sleep(int mils)方法:让当前线程休眠指定毫秒数,放弃cpu抢占权,和锁旗标(监控权)没有关系

  3. Thread.join():当前线程等待指定的线程结束后才能继续运行

  4. daemon:守护线程,服务员 Thread.setDaemon(true),为其他线程提供服务的线程。若进程中剩余的线程都是守护线程的话,则进程终止了。

  5. \(--\) 原子性操作

  6. 线程间通信,共享资源的问题。锁, 将并行转串行,防止并发访问。参照物,锁旗标

     //同步代码块
    synchronized(object lock){
    ...
    }

    同步代码块执行期间,线程始终持有对象的监控权,其他线程处于阻塞状态,只能等待

  7. 同步代码块是以当前所在对象做锁旗标

    synchronized(this) === 同步方法

  8. 同步静态方法,使用类作为同步标记

    public static synchronized xxxx(...){

    }

  9. wait()

    让当前线程进入到锁旗标的等待队列,释放cpu抢占权,还释放锁旗标的监控权。

    wait(1000); 设定等待时间,可以避免死锁

  10. notify()

    唤醒在等待队列中的线程,一次只通知一个线程

  11. notifyAll()

    通知所有线程可以抢占cpu和锁旗标监控权,解决死锁问题

    class ThreadDemo10{
    public static void main(String[] args){ Pool pool = new Pool(); Productor p1 = new Productor("生产者1",pool);
    p1.setName("p1");
    //Productor p2 = new Productor("生产者2",pool);
    Consumer c1 = new Consumer("消费者1",pool);
    c1.setName("c1");
    Consumer c2 = new Consumer("消费者2",pool);
    c2.setName("c2"); p1.start();
    //p2.start();
    c1.start();
    c2.start();
    }
    } //生产者
    class Productor extends Thread{
    private String name;
    private Pool pool;
    static int i = 0; public Productor(String name, Pool pool){
    this.name = name;
    this.pool = pool;
    } public void run(){
    //int i=0;
    while(true){
    pool.add(i++);
    }
    }
    } //消费者
    class Consumer extends Thread{
    private String name;
    private Pool pool;
    public Consumer(String name, Pool pool){
    this.name = name;
    this.pool = pool;
    } public void run(){
    while(true){
    pool.remove();
    }
    }
    } //票池
    class Pool{
    private java.util.List<Integer> list = new java.util.ArrayList<Integer>();
    //容器最大值
    private int MAX = 1; //添加元素
    public void add(int n){ synchronized(this){
    try{
    String name = Thread.currentThread().getName();
    while(list.size() == MAX){
    System.out.println(name+".wait()");
    this.wait();
    }
    list.add(n);
    System.out.println(name+"+: "+n);
    System.out.println(name+".notify()");
    this.notifyAll();
    }
    catch(Exception e){
    e.printStackTrace();
    }
    }
    } //删除元素
    public int remove(){ synchronized(this){
    try{
    String name = Thread.currentThread().getName();
    while(list.size() == 0){
    System.out.println(name+".wait()");
    this.wait();
    }
    int i = list.remove(0);
    System.out.println(name+"-:"+i);
    System.out.println(name+".notify()");
    this.notifyAll();
    return i;
    }
    catch(Exception e){
    e.printStackTrace();
    }
    return -1;
    }
    }
    }

作业

  1. 一共100个馒头,40个工人,每个工人最多能吃3个馒头,使用多线程输出所有工人吃馒头的情况

  2. 5辆汽车过隧道,隧道一次只能通过一辆汽车。每辆汽车通过时间不固定,

    机动车通过时间3秒,三轮车通过时间5秒,畜力车通过时间10秒,5辆车分别是2辆机动车,2辆畜力车,1辆三轮车,通过多线程模拟通过隧道的情况。提示:Car ThreeCar CowCar

  3. 用多线程模拟蜜蜂和熊的关系

    蜜蜂是生产者,熊是消费者,蜜蜂生产蜂蜜是累加的过程,熊吃蜂蜜是批量(满20吃掉)的过程,生产者和消费者之间使用通知方式告知对方,注意不能出现死锁现象。

    100只蜜蜂,每次生产的蜂蜜是1

    熊吃蜂蜜是20(批量的情况)

Java基础8-多线程;同步代码块的更多相关文章

  1. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

  2. JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this

    JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程 ...

  3. Java多线程同步代码块

    /*多线程的安全问题1.为什么会出现安全问题?因为程序在运行时,会出现一个线程在判断条件满足后,具备了执行资格,但没有运行代码后一个线程也判断了条件,也具备了执行资格,后一个线程运行了代码,但这时候, ...

  4. java中的synchronized同步代码块和同步方法的区别

    下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...

  5. 夯实Java基础(八)——代码块

    在Java中代码块指的是使用”{}”括起来的代码称为代码块.代码块一共分为4种:局部代码块,静态代码块,同步代码块,构造代码块. 1.局部代码块 局部代码块就是定义在方法体内部的代码块. public ...

  6. java的同步方法和同步代码块,对象锁,类锁区别

    /** * @author admin * @date 2018/1/12 9:48 * 作用在同一个实例对象上讨论 * synchronized同步方法的测试 * 两个线程,一个线程调用synchr ...

  7. Java的synchronized的同步代码块和同步方法的区别

    synchronized同步方法和同步代码块的区别 同步方法默认使用this或者当前类做为锁. 同步代码块可以选择以什么来加锁,比同步方法更精确,我们可以选择只有会在同步发生同步问题的代码加锁,而并不 ...

  8. java基础入门-多线程同步浅析-以银行转账为样例

    在说之前先普及一下线程是什么? 线程:说白了就是一个任务片段 进程:是一个具有独立功能的程序关于某个数据集合的一次执行活动.一个进程有一个或者多个线程 线程与进程的本质差别就是有么有数据共享空间.线程 ...

  9. “全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

随机推荐

  1. Python两大佬互相撕逼 技术何苦为难技术?

    最近两天 Python 圈发生了一件大事,两个 Python 大佬撕逼了起来了. 不,其实是一个大佬(刘志军)被怼. 事情是这样的. 背景 人物介绍: 董明伟:公众号「Python 之美」的作者,似乎 ...

  2. Jmeter录制手机app脚本

    转:http://www.cnblogs.com/yangxia-test/p/5484616.html   环境准备: 1.手机 2.wifi 3.Jmeter   具体步骤: 1.启动Jmeter ...

  3. SpringCloud入门(一)

    一.微服务概述 1.什么是微服务 目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事. 与微服务相对的叫巨石 ...

  4. Python——入门 | 常用python实现

    一.冒泡排序 list = [56,12,1,8,354,10,100,34,56,7,23,456,234,-58] def MP_paixu(): for i in range(len(list) ...

  5. linux中的&&,|| 与 () 命令

    用&&连接两个命令,前一命令执成功(返回0)下一命令才会执行, 如 date && echo 1 会打印1,而data && echo 2不会打印2 & ...

  6. 解决 MariaDB无密码就可以登录的问题

    问题: 困扰了很久的问题,, 使用apt-get来安装mysql,安装好之后发现安装的是 MariaDB,如下,无需密码既可以登录了.即使使用mysqladmin设置好密码,用密码登录可以,不用密码登 ...

  7. AttributeError type object 'deprecated' has no attribute 'ROCKY'

    AttributeError type object 'deprecated' has no attribute 'ROCKY' 在使用kolla安装docker的时候遇到了AttributeErro ...

  8. [python]获取当前路径用来构造相对路径的几种方法

    print('getcwd', os.getcwd()) print('sysargv', sys.argv) print('realpath', os.path.realpath(sys.argv[ ...

  9. java jdbc ResultSet结果通过java反射赋值给java对象

    在不整合框架的情况下,使用jdbc从数据库读取数据时都得一个个的get和set,不仅累代码还显得不简洁,所以利用java的反射机制写了一个工具类,这样用jdbc从数据库拿数据的时候就不用那么麻烦了. ...

  10. pta寒假作业2

    题目二币值转换 题目代码 #include<stdio.h> int main (void) { int n, initial_n; scanf("%d", & ...