多线程

创建线程的三种方式

/**
 * 实现线程的第一种方式:继承Thread类,重写run方法
 */
public class Test01 {
    public static void main(String[] args) {
        //获取线程对象
        ThreadImpl01 thread = new ThreadImpl01();
        //启动线程
        thread.start();
    }
}

class ThreadImpl01 extends Thread{
    @Override
    public void run() {
        System.out.println("线程程序开始执行...");
    }
}

/**
 * 实现线程的第二种方式:实现Runnable接口,重写run方法
 */
public class Test02 {
    public static void main(String[] args) {
        //获取线程对象
        ThreadImpl02 runnalbe = new ThreadImpl02();
        Thread thread = new Thread(runnalbe);
        //启动线程
        thread.start();
    }
}

class ThreadImpl02 implements Runnable{
    @Override
    public void run() {
        System.out.println("线程程序开始执行");
    }
}


/**
 * 实现线程的第三种方式:实现Callable接口
 *  特点:任务执行完后会有返回值
 */
public class Test03 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建一个"未来任务类对象"
        FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                System.out.println("线程程序开始执行");
                return 100;
            }
        });

        //创建线程对象
        Thread thread = new Thread(task);
        //启动线程
        thread.start();
        //获取线程的执行结果
        Object result = task.get();
        System.out.println(result);

    }
}

synchronized出现在三个位置的效果

public class SynchronizedTest {

    /**
     * synchronized同步代码块
     * synchronized(线程共享对象){
     *     同步代码块
     * }
     */
    public int test01() {
        synchronized (this) {
            int a = 1;
            int b = 2;
            return a + b;
        }
    }

    /**
     * 在实例方法上使用synchronized
     * 表示共享对象是this:synchronized(this){}  
     */
    public synchronized int test02(){
        int a = 1;
        int b = 2;
        return a + b;
    }

    /**
     * 在静态方法上使用synchronized
     * 表示共享对象是类锁:synchronized(xxx.class){}
     * @return
     */
    public synchronized static int test03(){
        int a = 1;
        int b = 2;
        return a + b;
    }
}

死锁代码实现:

public class DeadLock {
    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = new Object();

        MyThread1 t1 = new MyThread1(o1, o2);
        MyThread2 t2 = new MyThread2(o1, o2);

        t1.start();
        t2.start();
    }
}

class MyThread1 extends Thread{
    Object o1;
    Object o2;

    public MyThread1(Object o1, Object o2) {
        this.o1 = o1;
        this.o2 = o2;
    }

    @Override
    public void run() {
        synchronized (o1){
            System.out.println("t1线程获取到o1的对象锁,还需要获取到o2的对象锁");
            synchronized (o2){
                System.out.println("t1获取到o2的对象锁");
            }
        }
    }
}

class MyThread2 extends Thread{
    Object o1;
    Object o2;

    public MyThread2(Object o1, Object o2) {
        this.o1 = o1;
        this.o2 = o2;
    }

    @Override
    public void run() {
        synchronized (o2){
            System.out.println("t2线程获取到o2的对象锁,还需要获取到o1的对象锁");
            synchronized (o1){
                System.out.println("t2获取到o1的对象锁");
            }
        }
    }
}

Java定时器的实现

public class TimerTest {
    public static void main(String[] args) throws ParseException {
        //创建定时器对象
        Timer timer = new Timer();
        
        //指定定时任务
        //任务内容
        LogTimerTask task = new LogTimerTask();
        //开始执行时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date firstTime = sdf.parse("2020-8-29 12:45:00");
        /**
         * task:定时任务执行内容
         * firstTime:定时器开始执行时间
         * period:定时器每隔多久执行一次
         */
        timer.schedule(task, firstTime, 1000 * 10);
    }
}


class LogTimerTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("定时器正在执行定时任务...");
    }
}

生产者和消费者模式

/**
 * 1、使用wait方法和notify方法实现"生产者和消费者模式"
 * 2、什么是"生产者和消费者模式"?
 * 生产线程负责生产,消费线程负责消费
 * 生产线程和消费线程要达到一种平衡
 * 这是一种特殊的业务需求,在这种特殊的情况下需要使用wait方法和notify方法
 * 3、wait和notify方法不是线程对象的方法,是普通java对象的方法
 * 4、wait方法和notify方法建立在线程同步的基础之上。因为多线程要操作一个仓库。有线程安全问题
 * 5、wait方法作用:o.wait()让正在o对象上活动的线程t进入等待状态,并且释放掉t线程之前占有的o对象的锁
 * 6、notify方法作用:o.notify()让正在o对象上等待的线程唤醒,只是通知,不会释放o对象上之前被占用的锁
 * 7、模拟这样一个需求:
 * 仓库采用list集合
 * List集合假设只能存储1个元素
 * 1个元素就表示仓库满了
 * 如果List集合中元素个数是0,就表示仓库空了
 * 保证list集合中永远都是最多存储一个元素
 * <p>
 * 必须做到这种效果:生产1个消费1个
 */
public class Test01 {
    public static void main(String[] args) {
        //创建1个共享的仓库对象
        List list = new ArrayList();
        //创建两个线程对象
        //生产者线程
        Thread t1 = new Thread(new Producer(list));
        t1.setName("生产者线程");
        //消费者线程
        Thread t2 = new Thread(new Consumer(list));
        t2.setName("消费者线程");

        t1.start();
        t2.start();

    }
}

//生产线程
class Producer implements Runnable {
    //仓库
    private List list;

    public Producer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        //一直生产(使用死循环来模拟一直生产)
        while (true) {
            synchronized (list) {
                //仓库满了,停止生产
                if (list.size() > 0) {
                    try {
                        //释放list的对象锁
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                //仓库空了,开始生产
                String product = "产品";
                list.add(product);
                System.out.println(Thread.currentThread().getName() + "正在生产-->" + product);

                //唤醒消费线程
                list.notify();
            }
        }
    }
}

//消费线程
class Consumer implements Runnable {
    //仓库
    private List list;

    public Consumer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (list) {
                //仓库空了,停止消费
                if (list.size() == 0) {
                    try {
                        //释放list的对象锁
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                //仓库满了,开始消费
                list.removeAll(list);
                System.out.println(Thread.currentThread().getName() + "-->正在消费..");

                //唤醒生产线程
                list.notify();
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值