2.2.1 if条件语句
if条件语句是一个重要的编程语句,用于告诉程序在某个条件成立的情况下执行某段语句,而在另一种情况下执行另外的语句。
使用if条件语句,可选择是否要执行紧跟在条·件之后的那个语句。关键字if之后是作为条件的”布尔表达式”。如果该表达式返回的结果为true,则执行其后的语句;如果为false,则不执行if条件之后的语句。if条件语句可分为简单的if条件语句、if…else语句和if…else if多分支语句。
1.简单的if条件语句
语法如下
*布尔表达式:必要参数,表示最后返回的结果必须是一个布尔值。它可以是一个单纯的布尔变量或常量,也可以是使用关系或布尔运算符的表达式
*语句序列:可选参数。可以是一条或多条语句,当表达式的值为true时执行这些语句。若语句序列中仅有一条语句,则可以省略条件语句中的“{}”。
如果语句序列中只有一条语句,可以采用以下写法:
1 2 3 int a = 100 ; if (a == 100 ) System.out.println("a的值是100" );
过程如下:
【例2.1】判断手机号码是否存在
创建TP类,模拟拨打电话场景,如果电话号码不是84972266,则提示拨打号码不存在。
1 2 3 4 5 6 7 8 public class TP { public static void main (String[] args) { int Number = 123456789 ; if (Number != 84972266 ){ System.out.prinyln("对不起,您拨打的号码不存在!" ); } } }
2.if···else语句
if···else语句是条件语句中最常用的一种形式,它会针对某种条件有选择地做出处理。通常表现为“如果满足某种条件,就进行某种处理,否则就进行另一种处理”。语法如下:
1 2 3 4 5 if (条件表达式){ 语法序列1 }else { 语句序列2 }
if后面”( )”内的表达式的值必须是boolean型的。如果表达式的值为true,则执行紧跟if语句的复合语句;如果表达式的值为false,则执行else后面的复合语句。过程如下
【例2.2】使用if···else语句校验密码
在项目中创建Login类,在主方法中定义变量,并通过使用if···else语句判断变量的值来决定输出结果。
1 2 3 4 5 6 7 8 9 10 public class Login { public static void main (String[] args) { int password = 987654321 ; if (123456789 == password){ System.out.println("密码正确,欢迎登录" ); }else { System.out.println("密码错误,拒绝登录" ); } } }
3.if…else if多分支语句
if…else if 多分支语句用于针对某一事件的多种情况进行处理。通常表现为“如果满足某种条件,就进行某种处理,否则如果满足另一种条件则执行另一种处理”。语法如下
1 2 3 4 5 6 7 8 9 if (条件表达式1 ){ 语句序列1 }else if (条件表达式2 ){ 语句序列2 } ... else if (条件表达式n){ 语句序列n }
执行过程如图所示
【例2.3】使用if…else if语句实现饭店座位分配
创建rest类,声明整型变量count表示用餐人数,根据人数安排客人到4人桌,8人桌或包厢用餐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class rest { public static void main (String args[]) { System.out.println("欢迎光临,请问有多少人用餐?" ); int count = 9 ; System.out.println("回答:" +count+"人" ); if (count<=4 ){ System.out.println("客人请到大厅4人桌用餐" ); }else if (count>4 &&count<=16 ){ System.out.println("客人请到大厅8人桌用餐" ); }else if (count>8 &&count<=16 ){ System.out.println("客人请到楼上包厢用餐" ); }else { System.out.println("抱歉,我们店暂时没有这么大的包厢!" ); } } }
2.2.2 Switch多分支语句
在编程中,一个常见的问题就是检测一个变量是否符合某个条件。如果不符合,再用另外一个值来检测,以此类推。当然用if条件语句也可以完成。
例如,使用if语句对考试成绩进行评估,关键代码如下:
1 2 3 4 5 6 if (grade == 'A' ){ System.out.println("真棒" ); } if (grade == 'B' ){ System.out.println("做的不错" ); }
在Java中,可以用Switch语句将动作组织起来,以一个比较简单明了的方式来实现“多选一”的选择。语法如下:
1 2 3 4 5 6 7 8 9 10 11 12 switch (表达式){case 常量值1 : 语句块1 [break ;] ... case 常量值n: 语句块n [break ;] default : 语句块n+1 ; [break ;] }
switch语句中表达式的值必须是整型、字符型、字符串类型或枚举类型,常量值1~n的数据类型必须与表达式的值的类型相同。
switch语句首先计算表达式的值,如果表达式的计算结果和某个case后面的常量值相同,则执行该case语句后的若干个语句直到遇到break语句为止。此时,如果该case语句中没有break语句,将继续执行后面case中的若干个语句,直到遇到break语句为止。若没有一个常量的值与表达式的值相同,则执行default后面的语句。default语句为可选的,如果它不存在,且switch语句中表达式的值不与任何case的常量值相同,switch语句则不做任何处理。
注意 (1)同一个switch语句,case的常量值必须互不相同。 (2)在switch语句中,case语句后常量表达式的值可以为整数,但绝不可以是非整数的实数。例如,下面的代码就是错误的:
【例2.4】使用switch语句分为考试分数分级
创建Grade类,使用Scanner类在控制台输入分数,然后用switch多分支语句判断输入的分数属于哪类成绩。10分和9分属于优,8分属于良,7分和6分属于中,5分、4分、3分、2分、1分以及0分均属于差。
Java多线程基础 等待和唤醒 wait()
线程等待,等待的过程中,释放锁,需要其他线程调用notify去唤醒
notify()
唤醒一个等待的线程,如果有多个线程等待,则随机一条唤醒
notifyAll()
唤醒所有等待的线程
Lock锁 是一个接口
使用 获取 其 实现类 ReentrantLock
方法 lock()
获取锁
unlock()
释放锁
synchronized 与lock的区别 synchronized:不管是同步代码块还是同步方法,都需要在结束一对{}之后,释放锁对象
Lock:是通过两个方法控制需要被同步的代码,更灵活(两个方法为lock和unlock)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class MyTicket implements Runnable { int ticket = 100 ; Lock lock = new ReentrantLock (); @Override public void run () { while (true ) { try { Thread.sleep(100L ); lock.lock(); if (ticket > 0 ) { System.out.println(Thread.currentThread().getName() + \"买了第\" + ticket + \"张票\"); ticket--; } } catch (InterruptedException e) { throw new RuntimeException(e); }finally { lock.unlock(); } } } } public class Test01 { public static void main(String[] args) { MyTicket myTicket = new MyTicket(); Thread t1 = new Thread(myTicket, " 张三"); Thread t2 = new Thread(myTicket, " 李四"); Thread t3 = new Thread(myTicket, " 王五"); t1.start(); t2.start(); t3.start(); } }
Callable 接口,实现多线程的一种方式
Callable是一个接口,类似于Runnable
方法 1.V call()
设置线程任务,类似于run()
方法,与之不同的是call可以throw异常,并且还有返回值
2.call方法和run方法的区别:
a.相同点:都是设置线程任务的
b.不同点:
(1)call方法有返回值,而且有异常可以throws
(2)run方法没有返回值,而且有异常不可以throws
3.内容
a.是一个泛型接口。
b.泛型:用于指定我们操作什么类型的数据,<>中只能写引用数据类型,如果泛型不写,默认是Object类型数据。
c.实现Callable接口时,指定泛型是什么类型的,重写的call方法返回值就是什么类型的。
4.获取call方法返回值: FutureTask<V>
a. FutureTask<V>
实现了一个接口: Future <V>
b. FutureTask<V>
中有一个方法:
5.V get()
-> 获取call方法的返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class MyCallable implements Callable <String> { @Override public String call () throws Exception { return "ssssss" ; } } public class Test { public static void main (String[] args) throws ExecutionException, InterruptedException { MyCallable myCallable = new MyCallable (); FutureTask<String> futureTask = new FutureTask <>(myCallable); Thread t1 = new Thread (futureTask); t1.start(); System.out.println(futureTask.get()); } }
线程池 容器中有多条线程对象,来了线程任务,直接线程池中获取线程对象,用完还回去。
获取 1 static ExecutorService newFixedThreadPool (int nThreads)
执行线程任务 Futhre<?> submit(Runnable task)
提交一个Runnable任务用于执行
Future<T> submit(Callable<T> task)
提交一个Callable任务用于执行
返回值接口Futher 用于接收run方法或者call方法返回值的,但是run方法没有返回值,所以可以不用Future接收,执行call方法需要用Future接收
Future中有一个方法:V get() 用于获取call方法返回值
关闭
ExecutorService中的方法:
\nvoid shutdown() 启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务
练习 需求:创建两个线程任务,一个线程任务完成1-100的和,一个线程任务返回一个字符串
1 2 3 4 5 6 public class MyString implements Callable <String> { @Override public String call () throws Exception { return Thread.currentThread().getName(); } }
1 2 3 4 5 6 7 8 9 10 public class MySum implements Callable <Integer> { @Override public Integer call () throws Exception { int sum = 0 ; for (int i = 1 ; i <= 100 ; i++) { sum+=i; } return sum; } }
1 2 3 4 5 6 7 8 9 10 public class Test01 { public static void main (String[] args) throws ExecutionException, InterruptedException { ExecutorService es = Executors.newFixedThreadPool(2 ); Future<String> f1 = es.submit(new MyString ()); Future<Integer> f2 = es.submit(new MySum ()); System.out.println(f1.get()); System.out.println(f2.get()); } }