package com.phone.week5.day2;
public class Account {
private int money = 5000; //有余额5000
//可以查看余额
public int getMoney(){
return money;
}
//简单取款
public void takeMoney(int amt){
money = money-amt;
}
}
package com.phone.week5.day2;
/*
* 多线程操作的时候会出现线程安全的问题,
* 当一个线程在执行某个方法时,还没执行完,中间就被另一个线程打断了,也进入到这个方法里来执行,导致共享数据的错误
* 解决线程安全,需要同步就可以了
* 就是通过一个关键字,叫synchronized,它指的是同步的意思,意思就是加锁,给你操作的共享的数据加锁,加了锁之后,别的
* 线程就没有办法操作,只能等你这个线程把锁放掉,这样做就可以保证线程安全了
* 加锁有两种方式:
* 第一种,给方法加锁,给方法加锁(也叫同步方法),指的是给哪个对象加锁了呢?给this这个对象加锁了
* 第二种,同步代码块,就是在方法里,写一个同步代码块,里面传一个你要加锁的对象
*
* 要想实现线程同步,至少有两个条件
* 第一个,肯定要有两个以上的线程
* 第二个,多个线程要有共享的对象
*
* 一般来说,我们要给什么对象进行加锁呢?
* 给共享的对象进行加锁(给多个线程都操作的同一个对象进行加锁)
*
* 线程同步的目的:保证只有一个线程在操作共享的对象
*
* 同步的好处:解决了多线程安全的问题
* 同步的坏处:耗费资源,每个线程进来都要判断锁
*
* 四个窗口卖400张票
* 用同下代码块的方式和同步方法的方式来完成
*/
public class MyCount implements Runnable{
private Account acc = new Account();
@Override
public void run() {
for (int i = 0; i < 5; i++) {
//System.out.println("取款");
getAccount(1000);
if(acc.getMoney()==0){
System.out.println("帐户透支了");
}
}
}
public void getAccount(int money){
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
synchronized (acc) {
if(acc.getMoney()>=money){
System.out.println(Thread.currentThread().getName()+"准备取款");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
acc.takeMoney(money);
System.out.println(Thread.currentThread().getName()+"取款成功,余额还有:"+acc.getMoney());
}else{
System.out.println("余额不足,当前帐户余额是:"+acc.getMoney());
}
}
}
}
package com.phone.week5.day2;
import java.util.concurrent.atomic.AtomicInteger;
/*
*
*/
public class Test {
public static void main(String[] args) {
/*MyCount mc = new MyCount();
Thread t1 = new Thread(mc);
Thread t2 = new Thread(mc);
t1.setName("张三");
t2.setName("张三老婆");
t1.start();
t2.start();*/
UniqueThreadIdGenerator ut1 = new UniqueThreadIdGenerator();
UniqueThreadIdGenerator ut2 = new UniqueThreadIdGenerator();
UniqueThreadIdGenerator ut3 =new UniqueThreadIdGenerator();
System.out.println(ut1.getCurrentThreadId());
ut1.start();
ut2.start();
ut3.start();
}
}
package com.phone.week5.day2;
public class TestLock {
public static void main(String[] args) {
DeadLock dl = new DeadLock();
new Thread(dl).start();
new Thread(dl).start();
}
}
package com.phone.week5.day2;
import java.util.concurrent.atomic.AtomicInteger;
public class TH implements Runnable{
UniqueThreadIdGenerator uti = new UniqueThreadIdGenerator();
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"\t"+uti.getCurrentThreadId());
}
}
class UniqueThreadIdGenerator extends Thread{
private static final AtomicInteger uniqueId = new AtomicInteger(0);
public static final ThreadLocal < Integer > uniqueNum =
new ThreadLocal < Integer > () {
@Override protected Integer initialValue() {
System.out.println("aaaaa");
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueNum.get();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"\t"+getCurrentThreadId());
}
}