A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© duelxl 初级黑马   /  2019-10-28 17:34  /  975 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

线程/线程池总结一、线程自定义的线程创建代码:方法一:
新建一个类继承Thread,在里面重写run方法,run()方法里面写该线程需要执行的任务.
在需要实现多线程时创建该线程类的对象,调用start()方法.

import org.junit.Test;

//定义一个自定义线程,重写run()方法
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);
        }
    }
}

public class ThreadDemo {
//测试多线程
    @Test
    public void method01() {
        MyThread myThread = new MyThread();
        myThread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);

        }

    }
}
方法二:
使用匿名内部类,创建一个Runnable接口的匿名实现对象,重写里面的run方法.
然后使用Thread类的构造方法 Thread(Runnable runnable,String name)新建一个线程对象,再使用这个对象调用start()方法创建多线程


@Test
    public void method02() {
        for (int i = 0; i < 100; i++) {
            System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);
                }
            }
        }).start();

    }二、线程安全
线程安全:如果线程不安全,多个线程对同一个变量同时进行操作时,会产生延时或者操作多次的现象;
解决方案:使用同步锁或者lock()方法保证线程安全
同步锁:
实现类:
class Sales implements Runnable {
    int totals = 1000;
    Object object = new Object();

    @Override
    public void run() {
        while (true) {
            synchronized (object) {
                if (totals > 0) {
                    System.out.println("窗口" + Thread.currentThread().getName() + "正在卖倒数第" + totals + "张票");
                    totals--;
                } else {
                    break;
                }
            }
        }
    }
}
测试方法
    //测试同步锁(Test插件有问题,会执行不完,放到main()方法就没问题)
    @Test
    public void method03() {
        Sales sales = new Sales();
        Thread s1 = new Thread(sales, "ss1");
        Thread s2 = new Thread(sales, "ss2");
        Thread s3 = new Thread(sales, "ss3");
        Thread s4 = new Thread(sales, "ss4");
        s1.start();
        s2.start();
        s3.start();
        s4.start();
    }Lock类的lock方法解决线程安全:
Runnable实现类:
class Sales02 implements Runnable {
    private int totals = 1000;
    Lock lock = new ReentrantLock();
   
    @Override
    public void run() {
        while (true) {
            lock.lock();
            if (totals > 0) {
                System.out.println("窗口" + Thread.currentThread().getName() + "正在卖倒数第" + totals + "张票");
                totals--;
            } else {
                break;
            }
            lock.unlock();
        }
    }
}
测试方法
//测试Lock类对象解决线程安全(Test插件有问题,会执行不完,放到main()方法就没问题)
    @Test
    public void method04() {
        Sales02 sales = new Sales02();
        Thread s1 = new Thread(sales, "ss1");
        Thread s2 = new Thread(sales, "ss2");
        Thread s3 = new Thread(sales, "ss3");
        Thread s4 = new Thread(sales, "ss4");
        s1.start();
        s2.start();
        s3.start();
        s4.start();
    }
}
线程间的通信问题
消费者生产者案例:
包子铺线程做出包子,做完之后端上来,告诉客人可以吃.
客人吃完,告诉包子铺吃完了,让包子铺进行生产包子
包子类代码
class BaoZi {
    private String pi;
    private String xian;
    int situation = 0;

    public String getPi() {
        return pi;
    }

    public void setPi(String pi) {
        this.pi = pi;
    }

    public String getXian() {
        return xian;
    }

    public void setXian(String xian) {
        this.xian = xian;
    }

    public BaoZi(String pi, String xian) {
        this.pi = pi;
        this.xian = xian;
    }
}
包子铺线程类代码
//线程间的通信.包子铺类
class BaoZiPu extends Thread {
    private BaoZi bz;

    public BaoZiPu(BaoZi bz) {
        this.bz = bz;
    }

    @Override
    public void run() {
        while (true) {
            try {
                synchronized (bz) {
                    bz.wait(3000);
                    if (bz.situation == 1) {
                        bz.wait();
                    }
                    System.out.println("包子做好了,来,请慢用...");
                    bz.situation = 1;
                    bz.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
客人线程类代码
//线程间的通信.顾客类
class Customer extends Thread {
    BaoZi bz;

    public Customer(BaoZi bz) {
        this.bz = bz;
    }

    @Override
    public void run() {
        while (true) {
            try {
                synchronized (bz) {
                    bz.wait(3000);
                    if (bz.situation == 0) {
                        System.out.println("没包子了,快点做");
                        bz.wait();
                    }
                    System.out.println("包子上来了,我赶紧趁热吃.");
                    bz.situation = 0;
                    System.out.println("吃完了.");
                    bz.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
测试类
public static void main(String[] args) {
        BaoZi bz = new BaoZi("冰皮", "五仁");
        new Customer(bz).start();
        new BaoZiPu(bz).start();
    }
三、线程池
线程池使用 Executors中 的静态方法 newFixedThreadPool(int i) 方法创建,i为线程池中线程的数量.
把需要执行的任务写到一个Runnable实现类对象中,或者封装在一个匿名内部类或Lambda表达是中,调用线程池对象的submit方法把任务提交到线程池中执行.
代码:
ExecutorService service = Executors.newFixedThreadPool(5);
        service.submit(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() +"哈哈哈哈哈" +  i);
            }
        });
        service.submit(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() +"哈哈哈哈哈" +  i);
            }
        });
        service.submit(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println( Thread.currentThread().getName() +"哈哈哈哈哈" + i);
            }
        });
        service.submit(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() +"哈哈哈哈哈" +  i);
            }
        });

2 个回复

倒序浏览
不要等待机会,而是要创造机会。现在我来了,希望我们都可以坚持,早日用知识达到暴富
回复 使用道具 举报
发光并非太阳的专利,你也可以发光。加油
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马