/**
* @author wuyimin
* @create 2021-07-10-14:37
* @description
* 异步执行,成功回调,失败回调
*/
public class demo01 {
//今天才发现如果不是静态函数在java类内部的主函数是不能直接调用的
public static void main(String[] args) throws ExecutionException, InterruptedException {
//NoReturn();
HasReturn();
}
public static void NoReturn() throws ExecutionException, InterruptedException {
//Void泛型表示没有返回值
CompletableFuture<Void> completableFuture=CompletableFuture.runAsync(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-void");
});
System.out.println("正在等待执行结果");
System.out.println(completableFuture.get());//null
}
public static void HasReturn() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> completableFuture=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName()+"Integer");
return 1024;
});
//如果成功
Integer integer = completableFuture.whenComplete((t, u) -> {
System.out.println("t=" + t);//正常的返回结果
System.out.println("u=" + u);//错误的返回结果
//如果失败
}).exceptionally((e) -> {
System.out.println(e.getMessage());
return 233;//错误的返回结果返回
}).get();
System.out.println(integer);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/cbb0487562a09464d0abe4fb5157b8d4.png)
4组-8个操作
![](https://i-blog.csdnimg.cn/blog_migrate/bb84d4f1e1094ef63dbc4e49e06cbb69.png)
![](https://i-blog.csdnimg.cn/blog_migrate/90848464327a38e857c84ecbaf0cdd79.png)
规定:
![](https://i-blog.csdnimg.cn/blog_migrate/f4780d9d17e160212e4afed1727b0dd1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/430c689b14e2dc3316aa1a11215ac923.png)
保证可见性
public class JMM {
private static int num=0;
private volatile static int num2=0;
public static void main(String[] args) {
test02();
}
//这个方法的执行结果是能打印出1但是程序一直在执行死循环
public static void test01(){
new Thread(()->{
while(num==0){
System.out.println("循环中");
}
}).start();
try {
TimeUnit.SECONDS.sleep(2);
}catch (InterruptedException e){
e.printStackTrace();
}
num=1;
System.out.println(num);
}
//一开始在循环中,一旦num被修改就会停止,这里体现的是volatile关键字的可见性
public static void test02(){
new Thread(()->{
while(num2==0){
System.out.println("循环中");
}
}).start();
try {
TimeUnit.SECONDS.sleep(2);
}catch (InterruptedException e){
e.printStackTrace();
}
num2=1;
System.out.println(num2);
}
}
不保证原子性
public class NoAtom {
private volatile static int num=0;//即使加了volatile这个值依旧不是20000,但是 synchronized是保证的
private static void add(){
num++;
}
public static void main(String[] args) {
//理论是20000
for (int i = 0; i <20; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
add();
}
}).start();
}
while (Thread.activeCount()>2){//如果有超过两条线程在运行(java本身就有GC和main两条线程在进行)
Thread.yield();//线程礼让 让main线程放弃cpu给别的线程,等到其他线程死了再继续main线程
}
System.out.println(Thread.currentThread().getName()+" "+num);
}
}
如果不使用lock和synchronized如何保证原子性呢
num++并不是一个原子性操作,使用原子类来解决原子性问题
public class NoAtom {
private volatile static AtomicInteger num=new AtomicInteger();//原子类的Integer
private static void add(){
num.getAndIncrement();//类似num++但是是一个原子操作,CAS操作
}
public static void main(String[] args) {
//理论是20000
for (int i = 0; i <20; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
add();
}
}).start();
}
while (Thread.activeCount()>2){//如果有超过两条线程在运行(java本身就有GC和main两条线程在进行)
Thread.yield();//线程礼让 让main线程放弃cpu给别的线程,等到其他线程死了再继续main线程
}
System.out.println(Thread.currentThread().getName()+" "+num);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/84d78577817c5b212316e055726da875.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a184a0cc39cccb2691236bbf7ecc34be.png)
![](https://i-blog.csdnimg.cn/blog_migrate/861f1845d01d639e6798c3f344db1110.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ed1b4c9cf49e30a45e0acd555b765651.png)