1

多线程 thread/ runnable

1. 方案一:继承thread.

 1 package com.example.demo;
 2 
 3 
 4  
 5 //1. 方法1,继承thread类:Thread implements Runnable
 6 package com.example.demo;
 7 public class ThreadCreateDemo1 {
 8     public static void main(String[] args) {
 9         MyThread thread = new MyThread();
10         MyThread thread1 = new MyThread();
11         MyThread thread2 = new MyThread();
12         thread.start(); //该方法调用多次,出现IllegalThreadStateException
13         thread1.start(); //该方法调用多次,出现IllegalThreadStateException
14         thread2.start(); //该方法调用多次,出现IllegalThreadStateException
15     }
16 }
17 
18 class MyThread extends Thread {
19     @Override
20     public void run() {
21         //super.run();
22         System.out.println("hellow_world!");
23     }
24 }

2.方案二: 实现runnable.

 1 //2. 实现runnable:Thread(Runnable target)
 2 public class ThreadCreateDemo1 {
 3     public static void main(String[] args) {
 4         MyRunnable runnable = new MyRunnable();
 5         MyRunnable runnable1 = new MyRunnable();
 6         MyRunnable runnable2 = new MyRunnable();
 7         MyRunnable runnable3 = new MyRunnable();
 8        new Thread(runnable).start();
 9        new Thread(runnable1).start();
10        new Thread(runnable2).start();
11        new Thread(runnable3).start();
12        
13      }
14 }
15 
16 class MyRunnable implements Runnable {
17     public void run() {
18         System.out.println("通过Runnable创建的线程!");
19     }
20 }
21  

 

 3.案例

 

package cn.tedu.thread;



public class WaitNotifyDemo {
    public static void main(String[] args) {
        //创建学生类对象
        Student s=new Student();
        s.setName("lili");
        s.setGender('女');
        //开启线程
        new Thread(new Ask(s)).start();
        new Thread(new Change(s)).start();
    }
}


//线程所在的类---问问题
class Ask implements Runnable{
    // 引入学生类对象
    private Student s;

    public Ask(Student s){
            this.s=s;
        }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        //表示问问题的结果
        while(true){
            synchronized (s) {
                //释放线程执行权---等待
                if(s.flag==false)
                try {
                    s.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                //输出
                System.out.println
                ("老师你好,我是"+s.getName()
                +",是一个"+s.getGender()+
                "生,想问问题...");
                //唤醒线程
                s.notify();
                //改变布尔值
                s.flag=false;
                
            }
            
        }
    }
    
}




//线程所在的类---换学生
class Change implements Runnable{
    //引入学生类对象
    private Student s;
    public Change(Student s){
        this.s=s;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            synchronized (s) {
                //线程等待
                if(s.flag==true)
                try {
                    s.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                //
                if (s.getName().equals("tom")) {
                    s.setName("lili");
                    s.setGender('女');
                } else {
                    s.setName("tom");
                    s.setGender('男');
                }
                //线程唤醒
                s.notify();
                //改变布尔值
                s.flag=true;
            }
            
        }
    }}



//学生类
class Student{
    //属性
    private String name;
    private char gender;
    //
    boolean flag=true;
    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
}

 

 4.案例

 

package cn.tedu.thread;

public class SellTicketText1 {
    public static void main(String[] args) {
        //创建票类对象
        Ticket t=new Ticket();
        //设置票数
        t.setCount(100);
        
        //四个售票员
        Seller s1=new Seller(t);
        Seller s2=new Seller(t);
        Seller s3=new Seller(t);
        Seller s4=new Seller(t);
        /*
        //开启线程
        new Thread(s1,"A").start();
        new Thread(s2,"B").start();
        new Thread(s3,"C").start();
        new Thread(s4,"D").start();*/
        
        ////开启线程
         //*this指代当前类对象每个对象单独加锁---一个对象呗四个线程执行
        new Thread(s1,"A").start();
        new Thread(s1,"B").start();
        new Thread(s1,"C").start();
        new Thread(s1,"D").start();
    }
}

//卖票---线程的代码逻辑
class Seller implements Runnable{
    //引入票类
    Ticket t;
    //有参构造
    public Seller(Ticket t){
        this.t=t;
    }
    //线程代码逻辑---卖票的过程
    //同步方法锁
    @Override
    public synchronized void run() {
        // TODO Auto-generated method stub
        //卖票---循环
        while(true){//票卖结束就是票数为0
            //同步代码块锁---(锁对象)---被线程共享
            //synchronized (t) {//Math.class  Seller.class
                // 判断条件
                if (t.getCount() <= 0) {
                    break;
                }
                // 设置新的票数
                t.setCount(t.getCount() - 1);
                // 打印具体哪个售票员卖的---具体是哪个线程执行的
                // Thread.currentThread()---当前正在执行的线程
                System.out.println(Thread.currentThread().getName() + "卖了一张票,还剩" + t.getCount() + "票...");
            //}
            
        }
    }
    
}
//表示票类
class Ticket{
    //属性
    //票数
    private int count;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
    
}

 

使用继承方式的好处是方便传参,你可以在子类里面添加成员变量,通过set方法设置参数或者通过构造函数进行传递,而如果使用Runnable方式,则只能使用主线程里面被声明为final的变量。不好的地方是Java不支持多继承,如果继承了Thread类,那么子类不能再继承其他类,而Runable则没有这个限制。前两种方式都没办法拿到任务的返回结果,但是Callable方式可以

 

posted @ 2020-03-30 14:59  萌哥-爱学习  阅读(302)  评论(0)    收藏  举报