多线程03

线程03

1、观察线程状态

//观察测试线程状态
public class TestState {
    public static void main(String[] args) throws InterruptedException {
        //线程执行体
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("......");
        });

        //观察状态
        Thread.State state = thread.getState();
        System.out.println(state);//NEW

        //观察启动
        thread.start();//启动线程
        state = thread.getState();//持续观察线程
        System.out.println(state);//RUNNABLE

        while (state != Thread.State.TERMINATED){//只要线程不终止,就一直打印状态
            Thread.sleep(100);
            state = thread.getState();//更新线程状态
            System.out.println(state);
        }
    }
}
  • 一个线程结束后不能再次启动

2、线程的优先级

  • 设置优先级提高了CPU调度的可能性,但不是一定优先调度优先级高的线程
public class TestPriority {
    public static void main(String[] args) {
        //主线程默认优先级
        System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());

        MyPriority myPriority = new MyPriority();

        Thread t1 = new Thread(myPriority);
        Thread t2 = new Thread(myPriority);
        Thread t3 = new Thread(myPriority);
        Thread t4 = new Thread(myPriority);

        //先设置优先级在启动
        //1~10,越大优先级越高
        t1.start();

        t2.setPriority(Thread.MIN_PRIORITY);//1
        t2.start();

        t3.setPriority(Thread.NORM_PRIORITY);//5
        t3.start();

        t4.setPriority(Thread.MAX_PRIORITY);//10
        t4.start();


    }
}

3、静态代理

  1. 真实对象和代理对象都要实现同一个接口
  2. 代理对象能做更多的事
  3. 真实对象只需做自己专注的事
//静态代理
//代理能做许多自己本身做不到的事
public class StaticProxy {
    public static void main(String[] args) {
        You you = new You();//你
        WeddingCompany weddingCompany = new WeddingCompany(you);//你去婚庆公司办婚礼
        weddingCompany.HappyMarry();//婚庆公司帮你解决
    }

}
//结婚的接口,你与婚庆公司都要做的事。但婚庆公司还能帮你做其他事
interface Marry {
    void HappyMarry();
}

//你结婚
class You implements Marry{
    @Override
    public void HappyMarry() {
        System.out.println("你要结婚了");
    }
}

//婚庆公司帮你办好结婚
class WeddingCompany implements Marry{
    private Marry target;//结婚的客户

    //有参构造,传入目标客户
    public WeddingCompany(Marry target) {
        this.target = target;
    }

    @Override
    public void HappyMarry() {
        before();//婚前
        this.target.HappyMarry();//你结婚
        after();//婚后
    }

    private void before() {
        System.out.println("婚前布置现场");
    }

    private void after() {
        System.out.println("婚后收尾款");
    }

}

4、守护(daemon)线程

  • 线程分为用户线程和守护线程
  • 虚拟机必须确保用户线程执行完毕
  • 虚拟机不用等待守护线程执行完毕
//守护线程
//上帝守护着你
public class TestDaemon {
    public static void main(String[] args) {
        Me me = new Me();
        God god = new God();

        Thread thread = new Thread(god);
        thread.setDaemon(true);     //默认false,一般线程都是用户线程

        thread.start();//守护线程启动
        new Thread(me).start();//用户现场启动
    }
}

class God implements Runnable {
    @Override
    public void run() {
        //原本该循环是死循环,不会结束,但设置守护线程后,用户线程结束守护线程也会关闭,但需要一些时间
        while (true){
            System.out.println("上帝守护着我");
        }
    }
}

class Me implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("我每天开心的活着");
        }
        System.out.println("========Goodbye World=========");
    }
}

5、线程同步机制

  • 用到队列和锁

    • 队列就是排队,多个线程操作同一个对象时要按顺序来
    • 锁就好比排队上公厕,进入厕所后锁门,处理完后在出来
  • 先写一个不安全的案例,银行取钱

public class UnsafeBank {
    public static void main(String[] args) {
        //账户,只有100万
        Account account = new Account(100,"买房基金");

        //你取钱,50万
        Drawing you = new Drawing(account,50,"你");
        //你女朋友取钱,100万
        Drawing yourGirlfriend = new Drawing(account,100,"你女朋友");

        you.start();
        yourGirlfriend.start();
    }
}
//账户
class Account {
    int money;//余额
    String name;//卡名

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

//银行:模拟取款
class Drawing extends Thread{
    Account account;//账户

    //取了多少钱
    int drawingMoney;

    //现在的钱
    int nowMoney;

    public Drawing(Account account,int drawingMoney,String name){
        super(name);//谁取钱
        this.account = account;
        this.drawingMoney = drawingMoney;

    }

    @Override
    public void run() {
        //判断有没有钱
        if(account.money - drawingMoney < 0){
            System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
            return;
        }
        //用sleep放大问题的发生性
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //卡内余额 = 余额 - 你取的钱
        account.money = account.money - drawingMoney;

        //你手里的钱
        nowMoney = nowMoney + drawingMoney;

        System.out.println(account.name+"余额为:"+account.money);

        System.out.println(this.getName()+"手里的钱:"+nowMoney);
    }
}

同步方法synchronized,锁

  • 锁的是共享资源,要修改的量
  • synchronized方法控制对“对象”的访问,每个对象对应一把锁,每个synchronized方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞,方法一旦执行,就独占该锁,直到该方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行
  • 缺点就是效率变慢

synchronized(obj){}

  • 安全的取钱应该一个人取完在判断该账户的钱是否够下一个人取,而不是同时取
    @Override
    public void run() {
        synchronized(account){//锁的是修改的对象,也就是账户
            //判断有没有钱
            if(account.money - drawingMoney < 0){
                System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
                return;
            }
            //用sleep放大问题的发生性
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //卡内余额 = 余额 - 你取的钱
            account.money = account.money - drawingMoney;

            //你手里的钱
            nowMoney = nowMoney + drawingMoney;

            System.out.println(this.getName()+"手里的钱:"+nowMoney);

            System.out.println(account.name+"余额为:"+account.money);
        }

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值