作业解析

  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. (十五)The Search API

    Now let’s start with some simple searches. There are two basic ways to run searches: one is by sendi ...

  2. 网络安全实验室--SQL注入关

    第一关 万能密码:username='or '1'='1'#    password=1    即可登录得到flag. 第二关 最基础的注入,order by 判断字段数,然后 union selec ...

  3. 【区块链】【一】Hash 算法【转】

    问题导读1.哈希算法在区块链的作用是什么?2.什么是哈希算法?3.哈希算法是否可逆?4.比特币采用的是什么哈希算法? 作用在学习哈希算法前,我们需要知道哈希在区块链的作用哈希算法的作用如下:区块链通过 ...

  4. ubuntu安装docker{ubuntu16.04下安装docker}

       一.开始安装 第一步:   由于apt官方库里的docker版本可能比较旧,所以先卸载可能存在的旧版本: $ sudo apt-get remove docker docker-engine d ...

  5. Golang 入门系列(二)学习Go语言需要注意的坑

    上一章节我们已经了解了 Go 环境的配置,不了解的,请查看前面的文章 https://www.cnblogs.com/zhangweizhong/p/9459945.html,本章节我们将学习 Go ...

  6. 聊聊计算机中的编码(Unicode,GBK,ASCII,utf8,utf16,ISO8859-1等)以及乱码问题的解决办法

    作为一个程序员,一个中国的程序员,想来“乱码”问题基本上都遇到过,也为之头疼过.出现乱码问题的根本原因是编码与解码使用了不同而且不兼容的“标准”,在国内一般出现在中文的编解码过程中. 我们平时常见的编 ...

  7. 基于 WebGL 3D 的 HTML5 档案馆可视化管理系统

    前言 档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要实现档案流水化采集功能.为企事业单位的档案现代化管理,提供完整的解决方案,档 ...

  8. 全国天气预报信息数据 API 功能简介与代码调用实战视频

    此文章对开放数据接口 API 之「全国天气预报信息数据 API」进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用,并对实战开发进行了视频演示. 1. 产品功能 接口开放了 ...

  9. 关于toncat的Invalid character found in the request target.The valid characters are defined in RFC 7230 and RFC3986

    首先这个错误通常的产生原因, 是tomcat的确收到了格式不正确的请求参数,根据tomcat的版本支持的解析,tomcat抛出这个错误. 但是还有一种就是前台发送的请求方式由 get发送导致本应pos ...

  10. nginx代理部署Vue与React项目

    nginx代理部署Vue与React项目 一,介绍与需求 1.1,介绍 Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务.Nginx是由 ...