• 多线程 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方式可以

  • 相关阅读:
    gcc 编译
    UltraEdit 添加到右键菜单
    linux 编译错误:undefined reference to `__gxx_personality_v0'
    UltraEdit 取消生成.bak文件
    容器
    Windows CEvent事件
    Windows _beginthreadex 线程类与线程池
    C++ 工厂模式
    Mutex linux线程锁
    windows CRITICAL_SECTION 线程锁
  • 原文地址:https://www.cnblogs.com/mengbin0546/p/12598653.html
Copyright © 2020-2023  润新知