异步编程模型:两个线程之间谁也不等谁
同步编程模型:当一个线程必须等另外一个线程执行结束之后,线程才能执行
为什么引入线程同步?
为了数据的安全(暂时不考虑效率),线程同步使程序变了单线程。
什么情况下引入线程的同步?
1.多线程环境
2.多线程环境共享同一个数据
3.共享的数据涉及到修改操作
模拟银行的存款业务,引入线程的同步
对象过来找synchronized关键字,找到this锁就执行,找不到就等
public static void main(String[] args) {
Account act = new Account("Account01",5000.0);
Processor010 p = new Processor010(act);
//将两个线程合并为一个线程
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
t1.start();
t2.start();
}
}
class Account{
private String name;
private double balance;
public Account(String name, double balance) {
super();
this.name = name;
this.balance = balance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//取款方法
public void Withdraw(double money) {
/*t1线程执行的到此处,遇到了synchronized关键字,就回去找this对象的对象锁,如果找到则进入同步语句块中执行程序,当同步语句块中的代码执行结束之后,
*t1归还this的对象锁。
*
*在t1执行同步语句块的代码过程中,如果t2也过来执行以下代码,也遇到了synchronnized关键字,所以也去找this的对象锁,但是该对象的对象锁被t1持有,只能等待this对象的归还
*
* */
//共享对象
synchronized(this) {
double after = balance - money;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setBalance(after);
}
}
}
class Processor010 implements Runnable{
Account act;
Processor010(Account act){
this.act = act;
}
public void run() {
act.Withdraw(10000.0);
System.out.println("取款成功:余额"+act.getBalance());
}
}
//关键字添加在成员方法上,线程拿走的也是this的锁
public synchronized void Withdraw(double money) {
/*t1线程执行的到此处,遇到了synchronized关键字,就回去找this对象的对象锁,如果找到则进入同步语句块中执行程序,当同步语句块中的代码执行结束之后,
*t1归还this的对象锁。
*
*在t1执行同步语句块的代码过程中,如果t2也过来执行以下代码,也遇到了synchronnized关键字,所以也去找this的对象锁,但是该对象的对象锁被t1持有,只能等待this对象的归还
*
* */
double after = balance - money;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setBalance(after);
}
两种方法之下,第一种,放在下面的语句块中可以精确的去控制
synchronized详解01
public static void main(String[] args) throws InterruptedException {
myclass mc = new myclass();
Processor p = new Processor(mc);
Thread t1 = new Thread(p);
t1.setName("t1");
Thread t2 = new Thread(p);
t2.setName("t2");
t1.start();
//延迟
Thread.sleep(1000);
t2.start();
}
}
class Processor implements Runnable{
myclass mc;
Processor(myclass mc){
this.mc = mc;
}
public void run() {
if(Thread.currentThread().getName().equals("t1")) {
mc.m1();
}
if(Thread.currentThread().getName().equals("t2")) {
mc.m2();
}
}
}
class myclass {
public synchronized void m1() {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("m1");
}
//m2方法的执行不需要等m1方法的结束,没有synchronized
/*public void m2() {
System.out.println("m2");
}*/
public synchronized void m2() {
System.out.println("m2");
}
}
类锁——类只有一个,所以锁是类级别的,只有一个
static 中,用的是类锁,和对象锁无关,所以依然会synchronized等
public static void main(String[] args) throws InterruptedException {
myclass01 mc1 = new myclass01();
myclass01 mc2 = new myclass01();
Thread t1 = new Thread(new Processor0(mc1));
Thread t2 = new Thread(new Processor0(mc2));//等,下面用的是类锁,和对象锁无关
t1.setName("t1");
Thread.sleep(1000);
t2.setName("t2");
}
}
class Processor0 implements Runnable{
myclass01 mc ;
Processor0(myclass01 mc){
this.mc = mc;
}
public void run() {
if("t1".equals(Thread.currentThread().getName())) {
mc.m1();
}
if("t2".equals(Thread.currentThread().getName())) {
mc.m2();
}
}
}
class myclass01 {
public synchronized static void m1() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("m1");
}
//不等,因为没有synchronized
/*public static void m2() {
System.out.println("m2");
}*/
//等,程序执行需要类锁,而类锁只有一个
public synchronized static void m2() {
System.out.println("m2");
}
}
死锁
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
Thread t1 = new Thread(new T1(o1,o2));
Thread t2 = new Thread(new T2(o1,o2));
t1.start();
t2.start();
}
}
class T1 implements Runnable{
Object o1;
Object o2;
T1(Object o1,Object o2){
this.o1 = o1;
this.o2 = o2;
}
public void run() {
synchronized(o1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(o2) {
}
}
}
}
class T2 implements Runnable{
Object o1;
Object o2;
T2(Object o1,Object o2){
this.o1 = o1;
this.o2 = o2;
}
public void run() {
synchronized(o2) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(o1) {
}
}
}
}