1 打印信息
打印信息,在System.out
下面,主要有:
- print:标准输出,但是不会换行
- printf:可以使用类似C语言中的语法,进行格式化输出,即:
printf("%s", prama)
,printf
也不会换行 - println:输出完之后,会自动换行
代码:
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 定义数组
- 字符串数组:
String[] strings = new String[5]; //[]中指定数组的大小
,默认值是null
- 字节数组:
byte[] bytes = new byte[5];
,默认值是0
- 字符数组:
char[] chars = new char[5];
,默认值是\u0000
- 整数数组:
int[] ints = new int[5];
,默认值是0
- 浮点数数组:
double[] doubles = new double[5];
,默认值是0.0d
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张票,现实中是不存在这种情况的。
- 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();
}
}
}
- 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】,让我们一起成长,谢谢。