


package thread;
//不安全的买票
public class ThreeUnsafeCasesTicket {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"You").start();
new Thread(buyTicket,"I").start();
new Thread(buyTicket,"He").start();
}
}
class BuyTicket implements Runnable {
private int ticketNumber = 30;// 设置票数
boolean flag = true;
@Override
public void run() {
//买票
while (flag) {
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized void buy() throws InterruptedException {
if (ticketNumber <= 0) {// 如果票数小于等于零退出
flag = false;
return;
}
Thread.sleep(10);
//如果没有小于等于零执行下面的语句,who get ticket
System.out.println(Thread.currentThread().getName() + " get " + ticketNumber--);
}
}
线程同步是:多个线程操作同一个资源
并发:同一个对象被多个线程同事操作,联合查看
博客的 多线程——线程紊乱问题(没有解决)
线程同步:
1、现实生活中,我们会遇到“同一个资源,多个人都想
使用”的问题。
2、处理多线问题时,多个线程访问同一个对象,并且某
些线程还想修改最高对象。这个时候我们就使用线程
同步,线程同步其实就是一个等待的机制,多个需要
同时访问此对象的线程进入这个对象的等待池形成
队列,等待前面线程使用完毕,下一个线程在使用。
锁机制:由于同一线程的多个线程共享同一块存储空间,在带来
方便的同时,也带来了访问冲突问题,为了保证数据在
方法中被访问时的正确性,在访问时加入锁机制(synchronized),
当一个线程获得对象的排它锁,独占资源,其他线程必
须等待,使用后释放锁即可。锁机制存在的问题:
1、一个线程持有锁会导致其它说有需要此锁的线程挂起
2、在多线程竞争下,加锁,释放锁会导致比较多的上下
文切换和调度延时,引起性能问题
3、如果一个优先级高的线程等待一个优先级低的线程释放
锁会导致优先级倒置,引起性能问题
同步块

package thread;
// 同步块
// 不安全的取钱
public class ThreeUnsafeCasesBank {
public static void main(String[] args) {
Account account = new Account(500," savings ");
Drawing You = new Drawing(account,50," You ");
Drawing She = new Drawing(account,100," She ");
You.start();//开启 You 线程
She.start();
}
}
// 账户
class Account{
int money;// 余额
String name;// 用户名
public Account(int money, String name) {//构造器
this.money = money;//将构造器输入的 money 赋值给 Account 类的 money
this.name = name;
}
}
//银行
class Drawing extends Thread{
Account account;// 账户
int drawingMoney;// 设置取的钱
int nowMoney;// 设置现在手里的钱
public Drawing(Account account,int drawingMoney,String name){
super(name);// 设置超类名字,超类是 Thread 所以名字为 You 和 She
this.account=account;
this.drawingMoney=drawingMoney;
}
// 取钱
@Override
public void run() {
synchronized (account){
if(account.money-drawingMoney<0){// if 语句,如果账户余额不足需要退出
System.out.println(Thread.currentThread().getName()+"先生,您的余额不足。");
return;
}
try {//延迟,在账户余额还是 100 的时候让两个线程都跳过上面的 if 语句,避免执行 if 语句
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (Thread.currentThread().getName().equals(" You ")){// if 语句,在名字为 You的时候执行下面语句,
//写这句的原因,是在两个线程跑到下面计算语句的
//时候发现, account.money 还没有来得及获取
//到 account 的位置就又执行了下一个线程,与预
// 期不符,让其中一个线程在这暂停一下,给money有
//足够的时间给 account.money 赋值
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 卡取出后余额 = 账户.余额 - 取的钱
account.money = account.money - drawingMoney;
// 现在手里的钱 = 原来手里的钱 + 取的钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name+" balance is "+account.money);
//这里this.getName = Thread.currentThread().getName()
// 原因是这里的 name 刚好被 Thread 的 name 赋值了
System.out.println(this.getName()+" money is now "+nowMoney);
}
}
}

package thread;
import java.util.ArrayList;
public class ArrayListThread {
public static void main(String[] args) throws InterruptedException {
ArrayList<String> strings = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
synchronized (strings){
strings.add(Thread.currentThread().getName());// 添加一个集合的元素
}
}).start();
}
Thread.sleep(1000);// 延迟 1 秒
System.out.println(strings.size());// 返回集合的长度
}
}
&spm=1001.2101.3001.5002&articleId=108670857&d=1&t=3&u=56c0f5cb303f461fa8892c849fd415e1)
162

被折叠的 条评论
为什么被折叠?



