java基础知识介绍

1 打印信息

打印信息,在System.out下面,主要有:

  • print:标准输出,但是不会换行
  • printf:可以使用类似C语言中的语法,进行格式化输出,即:printf("%s", prama)printf也不会换行
  • println:输出完之后,会自动换行

printf用法

代码:

public class BasicDemo {
    public static void main(String[] args) {
        //输出
        System.out.printf("%s", new Integer(1));
        System.out.println("hello world.");
        System.out.print("hello world.");
    }
}

运行结果:

输出结果

2 循环控制结构

2.1 for循环
  • 方式1:for(int i=0;i<length;i++)
public class BasicDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("v");
        list.add("f");
        list.add("r");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}
  • 方式2:for(Object object : iterators)
public class BasicDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("v");
        list.add("f");
        list.add("r");
        for(String string : list){
            System.out.println(string);
        }
    }
}
  • 方式3:list.forEach(temp->{ ... })
public class BasicDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("v");
        list.add("f");
        list.add("r");
        list.forEach(temp->{
            System.out.println(temp);
        });
    }
}

运行结果:

输出结果

2.2 while循环
public class BasicDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("v");
        list.add("f");
        list.add("r");
        int index = 0;
        while(index < list.size()){
            System.out.println(list.get(index));
            index += 1;
        }
    }
}
2.3 do…while循环
public class BasicDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("v");
        list.add("f");
        list.add("r");
        int index = 0;
        do{
            System.out.println(list.get(index));
            index += 1;
        }while(index < list.size());
    }
}

while和do…while的区别:

  • do…while循环至少循环一次
  • while循环可以一次都不循环

3 if…else

public class BasicDemo {
    public static void main(String[] args) {
        int a = 1;
        if(a == 1){
            System.out.println("a is " + a);
        }else if (a == 2){
            System.out.println("a is " + a);
        } else{
            System.out.println("a is not 1");
        }
    }
}

4 获取用户输入

java中获取用户输入,通常情况下,使用java.util.Scanner类。Scanner具有以下的一些方法:

  • hasNext():判断是否有字符换输入
  • hasNextxxx():判断是否有与xxx对应的数据类型输入
4.1 如下面的代码(这里以输入int型整数为例):
public class BasicDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入整数,以非整数结束:");
        while (scanner.hasNextInt()){
            int s = scanner.nextInt();
            System.out.println("Your input:" + s);
            System.out.print("请输入整数,以非整数结束:");
        }
        scanner.close();
    }
}

结束条件:当输入的数据与hasNextxxx()中的xxx不相符时,退出。

运行结果:

输入整数

4.2 hasNext()输入任何字符
  • next()

    • 一定要读取到有效字符后才可以结束输入。
    • 一定要读取到有效字符后才可以结束输入。
    • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
    • next() 不能得到带有空格的字符串。
    public class BasicDemo {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入字符串,输入exit结束:");
            while (scanner.hasNext()){
                String s = scanner.next();
                if ("exit".equals(s)){
                    System.out.println("over");
                    break;
                }
                System.out.println("Your input:" + s);
                System.out.print("请输入字符串,输入exit结束:");
            }
            scanner.close();
        }
    }
    

    运行结果:

    输出结果

  • nextLine()

    • 以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
    • 可以获得空白。
    public class BasicDemo {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入字符串,输入exit结束:");
            while (scanner.hasNext()){
                String s = scanner.nextLine();
                if ("exit".equals(s)){
                    System.out.println("over");
                    break;
                }
                System.out.println("Your input:" + s);
                System.out.print("请输入字符串,输入exit结束:");
            }
            scanner.close();
        }
    }
    

结束条件:自己制定,在while循环中做判断。

5 switch…case

这是一个选择结构,类似if

public class BasicDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入字符串,输入exit结束:");
        while (scanner.hasNext()){
            String s = scanner.nextLine();
            switch (s){
                case "exit": break;
                case "abc":
                    System.out.println(s);
                    System.out.print("请输入字符串,输入exit结束:");
                    break;
                default: System.out.println("over");break;
            }
        }
        scanner.close();
    }
}

运行结果:

运行结果

6 数组

6.1 定义数组
  1. 字符串数组:String[] strings = new String[5]; //[]中指定数组的大小,默认值是null
  2. 字节数组:byte[] bytes = new byte[5];,默认值是0
  3. 字符数组:char[] chars = new char[5];,默认值是\u0000
  4. 整数数组:int[] ints = new int[5];,默认值是0
  5. 浮点数数组:
    1. double[] doubles = new double[5];,默认值是0.0d
    2. float[] floats = new float[5];,默认值是0.0f
6.2 给数组赋值

数组的赋值都是给指定下标进行赋值,这里以strings为例:

public class BasicDemo {
    public static void main(String[] args) {
        String[] strings = new String[5];  //[]中指定数组的大小
        strings[1] = "dddfd";
        for(int i=0;i<strings.length;i++){
            System.out.println(strings[i]);
        }
        
    }
}

输出结果:

运行结果

7 线程

7.1 通过实现Runable接口,来创建线程

RunableDemo.java代码:

public class RunableDemo implements Runnable {
    private String name;
    private Thread thread;

    public RunableDemo(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("当前线程:" + this.name);
        for (int i = 0; i < 5; i++) {
            System.out.println("第" + i + "次运行。");
        }
    }

    public void start(){
        if (thread == null){
            thread = new Thread(this, name);
            thread.start();
        }

    }
}

main.java代码:

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        RunableDemo runableDemo = new RunableDemo("我是runuable线程");
        runableDemo.start();
    }
}

运行结果:

运行结果

7.2通过集成Thread类,来创建线程

ThreadDemo.java

public class ThreadDemo extends Thread{
    private String name;
    private Thread thread;

    public void run(){
        System.out.println("当前线程->" + this.name);
        for (int i = 0; i < 5; i++) {
            System.out.println("第" + i + "次运行。");
        }
    }

    public void start(){
        if(this.thread == null){
            this.thread = new Thread(this,this.name);
            this.thread.start();
        }

    }
    public ThreadDemo() {
    }

    public ThreadDemo(String name) {
        this.name = name;
    }
}

main.java代码:

public class MainDemo {
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo("我是ThreadDemo线程");
        threadDemo.start();
    }
}

运行结果:

运行结果

7.3 使用Thread匿名调用

直接看代码:

public class MainDemo {
    public static void main(String[] args) {
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("第" + i + "次运行。");
            }
        }).start();
    }
}

运行结果:

运行结果

7.4 通过Callable来创建线程
  • 方式1:通过ExecutorService执行
import java.util.concurrent.*;

public class CallableDemo implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println("这是callable线程-->" + Thread.currentThread().getName());
        return 0;
    }

    public static void main(String[] args) {
        CallableDemo callableDemo = new CallableDemo();
        //定义一个线程池,有三个线程
        ExecutorService service = Executors.newFixedThreadPool(3);

        Future<Integer> res1 = service.submit(callableDemo);
        Future<Integer> res2 = service.submit(callableDemo);
        Future<Integer> res3 = service.submit(callableDemo);
        System.out.println(res1);
        System.out.println(res2);
        System.out.println(res3);
        service.shutdown();
    }
}

运行结果:

运行结果

  • 方式:通过FutureTask执行
import java.util.concurrent.*;

public class CallableDemo implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println("这是callable线程-->" + Thread.currentThread().getName());
        return 0;
    }

    public static void main(String[] args) {

        CallableDemo callableDemo = new CallableDemo();
        FutureTask futureTask = new FutureTask(callableDemo);
        new Thread(futureTask).start();
    }
}

运行结果:

运行结果

7.5 线程同步

当我们在使用多线程访问同一个资源并需要对其进行增删改时,如果某一时刻,有多个线程同时对该资源进行了修改,那么就会导致该资源的数据紊乱。那么解决办法就是,当某一个线程该资源时,就将该资源锁住,其他线程只有等待该线程执行完毕之后,才能对该线程进行修改。

先看一种线程不安全的同步代码:

public class Ticket implements Runnable{
    private int ticketNum = 10;
    private boolean flag = true;

    @Override
    public void run() {
        while (flag){
            buy();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void buy(){
        if (ticketNum > 0){
            System.out.println(Thread.currentThread().getName() + "-->" + ticketNum--);
        }else{
            flag = false;
            return;
        }
    }


    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(ticket,"aaa").start();
        new Thread(ticket,"bbb").start();
        new Thread(ticket,"ccc").start();
    }
}

运行结果:

运行结果

从图中我们可以到,有两个线程同时获得了第10张票,现实中是不存在这种情况的。

  1. synchronized

被synchronized修饰符修饰的变量或者方法,在同一时刻,只能被一个线程访问。使用synchronized修饰符将需要同步的资源“锁”起来,这样就可以避免多个线程同时竞争了。

  • 写法1:给修改同步资源的方法加上synchronized修饰符。
public class Ticket implements Runnable{
    private int ticketNum = 10;
    private boolean flag = true;

    @Override
    public void run() {
        while (flag){
            buy();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void buy(){
        if (ticketNum > 0){
            System.out.println(Thread.currentThread().getName() + "-->" + ticketNum--);
        }else{
            flag = false;
            return;
        }
    }


    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(ticket,"aaa").start();
        new Thread(ticket,"bbb").start();
        new Thread(ticket,"ccc").start();
    }
}
  • 写法2:将需要锁住的资源用()括起来,()中必须是一个对象,基本数据类型需要使用装饰类
public class Ticket implements Runnable{
    private static Integer ticketNum = 10;
    private boolean flag = true;

    @Override
    public void run() {
        synchronized (ticketNum){ //synchronized锁住的是一个对象,需要使用装饰类
            while (flag){
                buy();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void buy(){
        if (ticketNum > 0){
            System.out.println(Thread.currentThread().getName() + "-->" + ticketNum--);
        }else{
            flag = false;
            return;
        }
    }

    public static void main(String[] args) {
        synchronized (ticketNum){
            Ticket ticket = new Ticket();
            new Thread(ticket,"aaa").start();
            new Thread(ticket,"bbb").start();
            new Thread(ticket,"ccc").start();
        }
    }
}
  1. Lock锁

使用该锁,可以对需要同步的对象进行手动加锁,然后关锁。synchronized不能显式的指定加锁的位置,使用Lock可以手动给对象加锁。

import java.util.concurrent.locks.ReentrantLock;

public class Ticket implements Runnable {
    private static Integer ticketNum = 10;
    private boolean flag = true;

    private static final ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (flag) {
            buy();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void buy() {
        try {
            lock.lock();
            if (ticketNum > 0) {
                System.out.println(Thread.currentThread().getName() + "-->" + ticketNum--);
            } else {
                flag = false;
                return;
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        synchronized (ticketNum) {
            Ticket ticket = new Ticket();
            new Thread(ticket, "aaa").start();
            new Thread(ticket, "bbb").start();
            new Thread(ticket, "ccc").start();
        }
    }
}
7.6 线程间协程

消费者和生产者问题:当消费者需要消费某一个产品时,必须先由生产者生产出来,才能消费,否则就只能等待生产者生产。

public class ProducerCosumer {
    public static void main(String[] args) {
        Cache cache = new Cache();
        Producer producer = new Producer(cache);
        Cosumer cosumer = new Cosumer(cache);
        new Thread(producer).start();
        new Thread(cosumer).start();
    }
}

class Producer implements Runnable{
    Cache cache;

    public Producer(Cache cache) {
        this.cache = cache;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            cache.producing(new Prodcut(i));
            System.out.println("生产了" + i + "号产品");
        }
    }
}


class Cosumer implements Runnable{
    Cache cache;

    public Cosumer(Cache cache) {
        this.cache = cache;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            Prodcut prodcut = cache.cosuming();
            System.out.println("消费了" + prodcut.id + "号产品");
        }
    }
}


class Prodcut{
    int id;

    public Prodcut(int id) {
        this.id = id;
    }
}


class Cache{
    Prodcut[]  prodcuts = new Prodcut[10];
    int count = 0;

    public synchronized void producing(Prodcut prodcut) {
        if (count == prodcuts.length - 1){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        prodcuts[count] = prodcut;
        count++;
        this.notifyAll();
    }

    public synchronized Prodcut cosuming(){
        if (count == 0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        Prodcut prodcut = prodcuts[count];

        this.notifyAll();
        return prodcut;
    }

}

运行结果:

运行结果

写在最后

欢迎大家关注鄙人的公众号【麦田里的守望者zhg】,让我们一起成长,谢谢。
微信公众号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值