20 同步方法和同步代码块

package ThreadDemo;
//多个线程同时操作同一个对象,涉及到资源的独享与共享并发什么的
// 多个线程同时操作同一个对象,可能会出现问题:线程不安全,数据紊乱    ------>上锁
// 并发与同步
  // 火车票例子

// synchronized 锁住的是 操作者对象; synchronized 块 锁住的是 某个属性
public class Test20_Synchronized implements Runnable{
    boolean flag=true;
    int ticketNums=10;
    @Override
    public  void run() {
        while (flag){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            buy();
        }
    }

    private synchronized void buy() {   // synchronized 关键字,加锁 同步
            if (ticketNums==0){
                flag=false;
                return;
            }

            System.out.println(Thread.currentThread().getName()+"--->抢到了第"+ ticketNums-- +"张票");
            // Thread.currentThread().getName() :获得线程体的名字

    }

    public static void main(String[] args) {
        // 多个线程同时操作同一个对象,可能会出现问题------>上锁
        Test20_Synchronized ticket = new Test20_Synchronized();
        new Thread(ticket,"学生").start();  // 名为 学生线程体
        new Thread(ticket,"老师").start();  // 老师线程体
        new Thread(ticket,"黄牛").start();  // 黄牛线程体
    }
}
package ThreadDemo;

public class Test17_UnsafeBank {
    public static void main(String[] args) throws InterruptedException {
        Account account = new Account(100, "生活费");

        Bank bank = new Bank(account, "我", -20);
        new Thread(bank,"我").start();

        bank= new Bank(account,"哥哥",-40);  // 更新
        new Thread(bank,"哥哥").start();
    }
}


// 账户
class Account {
    int money;
    String name;  // 账户的名字
    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}

// 银行
class Bank implements Runnable{
    Account account;
    String name;   // 操作者(取钱或者存钱的人)
    int money;

    public Bank(Account account, String name,int money) {
        this.account = account;
        this.name = name;
        this.money= money;
    }

    @Override
    public void run() {
//  synchronized (){} 块:锁住某一特定的对象
        synchronized (account){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            account.money=account.money+money;
            if (account.money<=0){
                System.out.println("账户里面钱不够");
                return;
            }
            System.out.println(Thread.currentThread().getName()+"往账户里面:"+money);
            System.out.println("账户里面还剩:"+account.money);
        }

    }
}
package ThreadDemo;

import java.util.ArrayList;
import java.util.List;
// 线程可能不安全
/*
  1.买火车票
  2.银行取钱
  3.线程不安全的 数组列表
 */

public class Test18_UnsafeList {
    public static void main(String[] args) throws InterruptedException {
        List<String> list =new ArrayList<>();  // 存放 String 类型数据的 数组列表
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                synchronized (list){
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }

        Thread.sleep(1000);  // 必须添加sleep, 不然主线程就先执行了
        System.out.println(list.size()); 
    }
}
posted @   被占用的小海海  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示