领卓教育培训第十四天
正则表达式
定义
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
因此,典型的调用顺序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
构造摘要
- 字符
x 字符 x
\ 反斜线字符、 - 字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去) - 预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w] - POSIX 字符类(仅 US-ASCII)
\p{Lower} 小写字母字符:[a-z]
\p{Upper} 大写字母字符:[A-Z]
\p{Alpha} 字母字符:[\p{Lower}\p{Upper}]
\p{Digit} 十进制数字:[0-9]
\p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}]
\p{Punct} 标点符号:!”#$%&’()*+,-./:;<=>?@[]^_`{|}~ - Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
代码示例
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
//验证手机号
Pattern p1 = Pattern.compile("^(13|15|17|18)\\d{9}$");//规定格式
Matcher m1 = p1.matcher("13140168161");//要进行验证的字符串
boolean b1 = m1.matches();
System.out.println(b1);
//验证身份证号
Pattern p2 = Pattern.compile("^\\d{17}((\\d{1})|X)$");//规定格式
Matcher m2 = p2.matcher("13140168161452156X");//要进行验证的字符串
boolean b2 = m2.matches();
System.out.println(b2);
//验证密码
Pattern p3 = Pattern.compile("^(\\p{Alnum}){8,16}$");//规定格式
Matcher m3 = p3.matcher("131ASD68ad145215");//要进行验证的字符串
boolean b3 = m3.matches();
System.out.println(b3);
//验证网址
Pattern p4 = Pattern.compile("^w{3}\\.(\\p{Alnum})+\\.((com)|(cn)|(net)(org)$");//规定格式
Matcher m4 = p4.matcher("www.baidu.com");//要进行验证的字符串
boolean b4 = m4.matches();
System.out.println(b4);
//验证邮箱
Pattern p5 = Pattern.compile("^\\w+@\\w+(.com|.cn|.net){1,2}$");//规定格式
Matcher m5 = p5.matcher("yadg12_dt@1yt.com.cn");//要进行验证的字符串
boolean b5 = m5.matches();
System.out.println(b5);
}
}
线程
简介
- 线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
- 每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
创建线程
public class SellThread extends Thread{
@Override
public void run() {
for (int i = 1; i <=10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().toString()+i);
}
}
}
创建Test类
public class Test {
public static void main(String[] args) {
SellThread s1 = new SellThread();
SellThread s2 = new SellThread();
s1.start();
s2.start();
}
}
public class SellThread implements Runnable {
int i = 1;
String s = "abc";
@Override
public void run() {
while (i <= 10) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/*synchronized (s) {//同步代码块 if (i <= 10) { System.out.println(Thread.currentThread().toString() + i); i++; } }*/
sell();
}
}
private synchronized void sell(){ //同步方法
if (i <= 10) {
System.out.println(Thread.currentThread().toString() + i);
i++;
}
}
}
创建Test类
public class Test {
public static void main(String[] args) {
SellThread s = new SellThread();//共享数据
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start();
t2.start();
}
}
代码示例
有一个银行账户,两个人到这个账户取钱,每次取100元,余额不足100元,则不能取出!
创建Acccount类
public class Acccount implements Runnable {
Integer yue = 1090;
String s = "abc";
@Override
public void run() {
while(yue>=100) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s) {
if (yue >= 100) {
System.out.println(Thread.currentThread().toString()+"您已成功取出RMB:100元!");
} else {
System.out.println(Thread.currentThread().toString()+"对不起,您的余额不足!");
}
yue = yue - 100;
}
}
}
}
创建Test类
public class Test {
public static void main(String[] args) {
Acccount a = new Acccount();
Thread t1= new Thread(a);
Thread t2= new Thread(a);
t1.start();
t2.start();
}
}
运行结果:
死锁
创建SyncThread类
public class SyncThread implements Runnable {
private String s1;
private String s2;
public SyncThread(String o1,String o2) {
this.s1 = o1;
this.s2 = o2;
}
@Override
public void run() {
String name = Thread.currentThread().getName();//得到当前进程的名称
System.out.println(name + "刚进Run的锁" + s1);
synchronized (s1) {
System.out.println(name + "现在持有的锁" + s1);
sleep();
System.out.println(name + "等待的锁" + s2);
synchronized (s2) {
System.out.println(name + "内部持有的锁" + s2);
sleep();
}
System.out.println(name+"释放的内部锁"+s2);
}
System.out.println(name+"释放的外部锁"+s1);
System.out.println(name+"完成执行");
}
private void sleep() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
创建ThreadDeadLocked类
public class ThreadDeadLocked {
public static void main(String[] args) {
String s1="a";
String s2="b";
String s3="c";
SyncThread st1= new SyncThread(s1,s2);
SyncThread st2= new SyncThread(s2,s3);
SyncThread st3= new SyncThread(s3,s1);
Thread t1 = new Thread(st1);
Thread t2 = new Thread(st2);
Thread t3 = new Thread(st3);
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
}
}
运行结果:程序阻塞
Join()
简介
public final void join()throws InterruptedException
等待该线程终止。
抛出: InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。
代码示例
public class MyThread1 implements Runnable{
@Override
public void run() {
System.out.println("线程1开始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1结束");
}
}
public class MyThread2 implements Runnable {
@Override
public void run() {
System.out.println("线程2开始");
System.out.println("线程2结束");
}
}
public class Test { //join
public static void main(String[] args) {
MyThread1 myThread1 = new MyThread1();
MyThread2 myThread2= new MyThread2();
Thread t1 = new Thread(myThread1);
Thread t2 = new Thread(myThread2);
t1.start();
try {
t1.join();//必须等到t1执行完,之后再执行t2
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
运行结果:
wait()和notify()
简介
这两个方法在java.lang.object类里边
1. public final void wait()throws InterruptedException
当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。
2. public final void notify()唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争。
代码示例
创建MyThread1类
public class MyThread1 implements Runnable{
private String s="abc";
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s) {
try {
System.out.println(Thread.currentThread().getName()+"开始等待");
s.wait();
System.out.println(Thread.currentThread().getName()+"结束等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
创建
public class MyThread2 implements Runnable {
private String s="abc";
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s) {
System.out.println(Thread.currentThread().getName()+"唤醒前");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s.notify();
}
System.out.println(Thread.currentThread().getName()+"唤醒后");
}
}
创建Test类
public class Test { //wait()和notify()的用法
public static void main(String[] args) {
MyThread1 myThread1 = new MyThread1();
MyThread2 myThread2= new MyThread2();
Thread t1 = new Thread(myThread1);
Thread t2 = new Thread(myThread2);
t1.start();
t2.start();
}
}
运行结果:
生产者和消费者问题
生产者与消费者模型中,要保证以下几点:
1. 同一时间内只能有一个生产者生产
2. 同一时间内只能有一个消费者消费
3. 生产者生产的同时消费者不能消费
4. 消费者消费的同时生产者不能生产
5. 共享空间空时消费者不能继续消费。消费前判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行
6. 共享空间满时生产者不能继续生产。生产前判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行
代码示例
创建MakeProductThread类
//生产产品
public class MakeProductThread implements Runnable {
private ProductData product;
public MakeProductThread(ProductData product){
this.product=product;
}
@Override
public void run() {
while(true){
product.make();
}
}
}
创建ConsumeProductThread类
//消费产品
public class ConsumeProductThread implements Runnable{
private ProductData product;
public ConsumeProductThread(ProductData product){
this.product=product;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000); //消费者每次等待生产之后再消费
} catch (InterruptedException e) {
e.printStackTrace();
}
product.consume();
}
}
}
创建ProductData类
//产品数据共享
public class ProductData {
private boolean isProduct=false;
public synchronized void make(){
if(isProduct){//没有产品,开始生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("开始生产产品");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产了一件产品");
isProduct=true;
notify();//有产品,通知消费
}
public synchronized void consume(){
if(!isProduct){//没有产品,等待生产
System.out.println("等待商家生产产品");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("商家生产完成");
System.out.println("开始消费产品");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费产品完成");
System.out.println("----------");
isProduct=false;
notify();//消费完成,通知生产
}
}
创建Test类
public class Test {
public static void main(String[] args) {
ProductData product = new ProductData();
MakeProductThread mpt = new MakeProductThread(product);
ConsumeProductThread cpt = new ConsumeProductThread(product);
Thread t1 = new Thread(mpt);//生产
Thread t2 = new Thread(cpt);//消费
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
运行结果: