漫漫Java学习路,第十六天

package cn.tedu.thread;
//本类用于多线程编程实现方案1:继承Thread类的方式来完成
public class TestThread1 {
    public static void main(String[] args) {
        /*4.new对应的是线程的新建状态*/
        /*5.要想模拟多线程,至少得启动2个线程
        * 如果只启动一个线程,是单线程程序*/
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();
        MyThread t4 = new MyThread();
        /*6.这个run()如果直接这样调用,是没有多线程抢占执行的效果的
        * 这个写法只是把代码看做是普通方法来调用,谁先调用,谁先执行*/
//        t1.run();
//        t2.run();
//        t3.run();
//        t4.run();
        /*7.start()对应的状态就是就绪状态,会把刚刚新建好的线程加入到就绪队列之中
        * 至于这个线程什么时候执行,这就是多线程执行的随机性,需要等待OS选中并分配CPU*/
        /*8.线程的执行具有随机性,也就是说t1-t4具体怎么执行
        * 取决于CPU的调度与时间片的分配,我们是决定不了的*/
        /*9.执行start()时,底层会自动调用我们重写的,包含自己业务的run()*/
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
class MyThread extends Thread{
    /*1.多线程编程实现方案1:继承Thread类+重写run()*/
    @Override
    public void run() {
        /*2.super.run()表示的是调用父类的业务
        * 我们现在想用自己的业务,所以注释掉*/
        //super.run();
        for (int i = 0; i < 10; i++) {
            /*3.getName()表示可以获取当前正在执行的线程名称
            * 由于本类继承了Thread类,所以可以直接使用Thread类的这个方法*/
            System.out.println(i+"="+getName());
        }
    }
}
package cn.tedu.thread;
//本类用于多线程编程实现方案2:实现Runnable接口来完成
public class TestThread2 {
    public static void main(String[] args) {
        //目标业务类对象
        MyRunnable target = new MyRunnable();
        /*如何以多线程的方式启动线程,需要调用start()
        * 自己没有,需要与Thread类建立联系:Thread(Runnable target)
        * 但是由于Runnable是接口,无法实例化,我们可以把接口实现类对象
        * 也就是我们的自定义类的对象作为构造函数的参数传入,与Thread类建立联系*/
        Thread t1 = new Thread(target);
        Thread t2 = new Thread(target);
        Thread t3 = new Thread(target);
        Thread t4 = new Thread(target);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        StringBuilder s = new StringBuilder();
        s.append(s);
    }
}
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 30; i++) {
            /*问题:自定义父类与父接口Runnable中都没有获取线程名字的方法
            * 所以还需要从Thread类中找:
            * currentThread():静态方法,获取当前正在执行的线程对象
            * getName():非静态方法,有刚刚获取到的线程对象调用,返回当前线程对象的名字*/
            System.out.println(i+"="+Thread.currentThread().getName());
        }
    }
}
package cn.tedu.tickets;
/*需求:设计多线程模型,4个售票窗口共计售票100张
 * 本方案使用多线程编程实现方案2:实现Runnable接口的方式来完成*/
public class TestRunnable {
    public static void main(String[] args) {
        TicketRunnable target = new TicketRunnable();
        Thread t1 = new Thread(target);
        Thread t2 = new Thread(target);
        Thread t3 = new Thread(target);
        Thread t4 = new Thread(target);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
class TicketRunnable implements Runnable{
    /*由于自定义类对象,作为唯一的业务对象,只new了一次
    * 所以发布的任务,也就是票数天然的会被所有线程对象共享,无需设置为静态也只有一份*/
    int ticket = 100;
    @Override
    public void run() {
        while(true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(ticket<=0) break;
            System.out.println(Thread.currentThread().getName() + "=" + ticket--);
        }
    }
}
package cn.tedu.tickets;
/*需求:设计多线程模型,4个售票窗口共计售票100张
* 本方案使用多线程编程实现方案1:继承Thread类的方式来完成*/
public class TestThread {
    public static void main(String[] args) {
        TicketThread t1 = new TicketThread("窗口一");
        TicketThread t2 = new TicketThread("窗口二");
        TicketThread t3 = new TicketThread("窗口三");
        TicketThread t4 = new TicketThread("窗口四");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
class TicketThread extends Thread{
    /*问题:4个线程对象共计售票400张,原因是创建了4个本类对象,鸽子操作鸽子的成员变量
    * 解决:让所有对象共享同一个变量,这个变量需要设置为静态的*/
    static int tickets = 100;
    /*添加本类的含餐构造,用于给线程对象起名字
    * 由于只添加了这一个含参构造,默认的无参构造被覆盖掉了*/
    public TicketThread(String name) {
        /*表示调用父类的含参构造,因为实际上起名的功能是父类完成的
        * 所以我们需要将本构造函数接到的名字参数,传给父类的构造函数,让父类起名字*/
        super(name);
    }

    @Override
    public void run() {
        while(true){
            /*让每个线程经历休眠,增加线程状态切换的频率与出错的概率,产生了问题
            * 问题1:产生了重卖的现象:同一张票卖给了多个人
            * 问题2:产生了超卖的现象:超出了规定的票数,出现了0 -1 -2这样的票*/
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(getName()+"="+tickets--);
            if (tickets<=0) break;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值