Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

Java连载107-join方法、锁(synchronized)机制以及原理

心悦君兮君不知-睿 2020-04-10 00:14:00 阅读数:19 评论数:0 点赞数:0 收藏数:0

一、join方法

1.该方法为成员方法

2.线程合并

 

package com.bjpowernode.java_learning;
​
public class D107_1_JoinMethod {
public static void main(String[] args) throws InterruptedException{
Thread t = new Thread (new Processer107());
t.setName("t");
t.start();
//合并线程

t.join();//t和主线程合并,可以理解为两个栈合并成一个栈了,也就是子线程与主线程合并成一个单线程了
//主线程
for(int i=0;i<5;i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}
class Processer107 implements Runnable{
public void run() {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}

 

 

 

二、线程的同步(加锁)

1.异步编程模型:线程与线程之间,独立执行,谁也不等谁​。

2.同步编程模型​:线程与线程之间,先执行一个,再执行另一个,有执行的先后顺序。

3.​什么时候要同步?为什么​引入线程同步?

(1)​为了数据安全,例如:银行取款​。但是为了​保证数据是安全的,必须加入线程同步机制;

(2)​使用线程同步的情形:i.必须是​多线程环境;ii.多线程环境共享一个数据;iii.​共享的数据涉及到修改操作。

以下程序演示取款例子(这个不使用同步的机制,看看会产生什么影响)

package com.bjpowernode.java_learning;
​
public class D107_2_SynchronizedMethod {
public static void main(String[] args) throws InterruptedException{
//创建一个公共账户

Accout107_2 a = new Accout107_2("actno-001",8000.0);
Processer107_2 c = new Processer107_2(a);
//创建线程对同一个账户进行取款

Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
class Accout107_2 {
private String actno;
private double balance;
public Accout107_2(String actno,double balance) {
this.actno = actno;
this.balance = balance;
}
​
public String getActno() {
return actno;
}
​
public void setActno(String actno) {
this.actno = actno;
}
​
public double getBalance() {
return balance;
}
​
public void setBalance(double balance) {
this.balance = balance;
}
//对外提供一个取款的方法
public void withdraw(double money) {
double after = this.balance - money;
try {
//这里我们故意延迟了一下,可以看出余额不对了

Thread.sleep(1000);
}catch(InterruptedException e){
}
this.setBalance(after);
}
}
class Processer107_2 implements Runnable{
//账户

Accout107_2 act;
//Constructer
public Processer107_2(Accout107_2 act) {
this.act = act;
}
public void run() {
act.withdraw(1000.0);
System.out.println("取款成功,余额为:"+act.getBalance());
}
}

修改一下代码,来解决上面的问题

我们只需要修改withdram方法即可

public void withdraw(double money) {
//把需要同步的代码,放到同步语句块中,参数一定要填共享对象
synchronized(this) {
double after = this.balance - money;
try {
//这里我们故意延迟了一下,可以看出余额不对了

Thread.sleep(1000);
}catch(InterruptedException e){
}
this.setBalance(after);
}
}

​总结:加入线程同步机制​,可以保证我们的数据是安全的,并且是准确,但是这也是牺牲性能为前提的。

三、synchronized的原理

t1线程和t2线程,t1线程执行到synchronized关键字,就会找this对象的对象锁,如果找到this对象锁,则进入到同步语句块中执行程序,当同步语句块中的代码执行结束汉字过后,t1线程​归还this的对象锁。

在t1线程执行同步语句块的过程中,如果t2线程也过来执行以下代码,也遇到了synchronized关键字,所以也去找this的对象锁,但是该对象锁被t1线程持有,只能在这等待this对象锁​归还。​

四、源码:

D107_1_JoinMethod.java

D107_2_SynchronizedMethod.java

https://github.com/ruigege66/Java/blob/master/D107_1_JoinMethod.java

https://github.com/ruigege66/Java/blob/master/D107_2_SynchronizedMethod.java

2.CSDN:https://blog.csdn.net/weixin_44630050

3.博客园:https://www.cnblogs.com/ruigege0000/

4.欢迎关注微信公众号:傅里叶变换,个人公众号,仅用于学习交流,后台回复”礼包“,获取大数据学习资料

 

 

版权声明
本文为[心悦君兮君不知-睿]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/ruigege0000/p/12670712.html