Java多线程学习笔记(三)同步和异步

时间:2023-03-09 19:49:48
Java多线程学习笔记(三)同步和异步

首先是一段代码:

 public class HasSelfPrivateNum {
public void addI(String username){
try {
int num=0;
if(username.equals("a")){
num=100;
System.out.println("a set over! ");
Thread.sleep(2000);
}else{
num=200;
System.out.println("b set over! ");
}
System.out.println(username+" num="+num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

上述代码中的含义是HasSelfPrivateNum对象的A和B的判断

之后有两个线程:

 public class ThreadA extends Thread {
private HasSelfPrivateNum numRef;
public ThreadA(HasSelfPrivateNum numRef){
super();
this.numRef=numRef;
} public void run(){
super.run();
numRef.addI("a");
}
}
 public class ThreadB extends Thread{
private HasSelfPrivateNum numRef;
public ThreadB(HasSelfPrivateNum numRef){
super();
this.numRef=numRef;
} public void run(){
super.run();
numRef.addI("b");
}
}

我们可以看出来线程A和线程B中我们创建了HasSelfPrivateNum实例。

Java多线程学习笔记(三)同步和异步

运行结果中可以看出来,这个程序不存在非线程安全性问题,为什么呢,因为这个变量是方法内部的,方法内部的变量是私有的特性造成了线程安全,并且这个其本身永远线程安全。接下来吧int num这一行代码放在方法之外我们会看到什么呢?

Java多线程学习笔记(三)同步和异步

这时我们会看到线程不安全了,两个对象同时操作了业务中的实例变量,所以发生了线程不安全的问题,原因是没有同步,为了让线程安全我们可以家一个同步锁来解决这个问题:

Java多线程学习笔记(三)同步和异步

加了同步锁之后运行就安全了,直到A线程执行完成之后在会执行B线程,如果一个线程没有执行完毕,那么其他线程就无法访问这个线程。和之前那个同步锁的道理是一样的,这就是线程的同步.

以上就是线程同步的道理;

下面是线程的异步:

在刚才的程序上在修改main方法中的代码为:

Java多线程学习笔记(三)同步和异步

同时创建两个对象然后再两个线程中运行我们会发现运行结果:

Java多线程学习笔记(三)同步和异步

我们现在比较一下两个结果:

Java多线程学习笔记(三)同步和异步Java多线程学习笔记(三)同步和异步

我们会发现在同步的时候,执行方式为执行A线程直到A线程完全执行完毕之后,再去执行B,原因是因为只有一个Has对象,资源存在竞争关系,当我们使用同步锁的时候就会受到同步机制的影响,当A线程占用了这个对象的资源的时候,其他线程就无法访问这个资源了,直到A执行完毕之后,释放了这个资源,这个时候B线程才有资格去拿到这个线程.我们把这个机制叫做同步.

那个第二个输出方式就和前一个不一样了,这种打印效果就是异步的.两个线程访问了两个不同的对象,这两个不同的对象产生了两个锁,所以一个线程中一个对象的锁并锁不住其他对象,所以就会这样输出.

结论:Java中synhronized关键字锁住的是一个对象,而不是一个方法或者一段代码.

=========================================

Java多线程学习笔记(三)同步和异步

Java多线程学习笔记(三)同步和异步