作业解析

  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. 关于wxpython多线程研究包括(import Publisher等错误研究)

    作为一个自动化测试人员,开发基本的应用桌面程序是必须的!最近在研究wxpython相关知识,目前看到多线程一块,发现官方文档介绍说:"在线程中不能修改修改窗口属性!",但是实际情况 ...

  2. 安装软件the error code is 2203解决方法

    win10安装mysql5.7的时候弹出这个2203错误,记录一下. 解决方法: 按照下面路径,去掉只读解决了.

  3. 【转】IT行业岗位以及发展方向

    以下转自https://blog.csdn.net/qq_23994787/article/details/79847270 职业生涯规划的意义 1.以既有的成就为基础,确立人生的方向,提供奋斗的策略 ...

  4. springcloud

    基本术语 1.服务器 服务器:是提供计算服务的设备.由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力.服务器的构成:包括处理器.硬盘.内存.系统总线等,和通用 ...

  5. kettle基于时间戳增量更新

    思路1: 1.提前建好ts时间表,设置两个字段分别为current_t和load_t,current用于比较原表中日期的上限,load_t则为上次加载的日期,几位原表中日期的下限. create ta ...

  6. ABP中的拦截器之ValidationInterceptor(下)

    在上篇我分析了整个ABP中ValitationInterceptor的整个过程,就其中涉及到的Validator过程没有详细的论述,这篇文章就这个过程进行详细的论述,另外任何一个重要的特性如何应用是最 ...

  7. Python——爬虫——数据提取

    一.XML数据提取 (1)定义:XML指可扩展标记语言.标记语言,标签需要我们自行定义 (2)设计宗旨:是传输数据,而非显示数据,具有自我描述性 (3)节点关系:   父:每个元素及属性都有一个父. ...

  8. 使用jenkins进行前端项目自动部署

    前面的话 后端的nodeJS项目可以使用pm2进行自动部署,由于前端项目打包后是静态资源,不需要进程守护.一般地,前端项目使用jenkins来进行自动部署,包括打包.测试等一系列流程.本文将详细介绍j ...

  9. 【数学建模】MATLAB语法

    一.向量.矩阵的表示和使用 format long  %小数很多format short %默认4位小数format rat %显示最近的分数format short e %指数格式的数 尾数多少 e ...

  10. Qt如何去掉按钮等控件的虚线框(焦点框)

    方法1:可以通过代码ui->pushButton->setFocusPolicy(Qt::NoFocus)或在Qt Creator的属性列表中设置. 方法2:如果在嵌入式设备中需要通过按键 ...