继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Java多线程基础学习总结

亚努人
关注TA
已关注
手记 20
粉丝 36
获赞 349

要实现多线程的开发,就像必须存在主类那样,也需要一个线程主体类,这个类必须继承Thread类或实现Runable接口。此外还需在该类中覆写run()方法。

1、多线程的实现方式

以下代码是通过继承Thread类实现多线程的开发。线程主体要写在run()方法里,通过在main()方法里实例化线程类,获取线程对象。再通过线程对象的start()方法启动线程,此时3个线程将会并发执行。

public class MyThread extends Thread {
    private String name;
    public MyThread(String name){
        this.name = name;
    }
    @Override
    public void run() {
        for(int i=1;i<=5;i++){
            System.out.println(this.name+":i="+i);
        }
    }

    public static void main(String[] args) {
        MyThread a = new MyThread("线程A");
        MyThread b = new MyThread("线程B");
        MyThread c = new MyThread("线程C");
        a.start();
        b.start();
        c.start();
    }
}

执行结果是3个线程并发执行(如下图)。当不使用start()方法启动线程而是调用run()方法时,程序将会像调用普通方法一样顺序执行。
图片描述

利用Runnable接口实现卖票的程序例子。

public class Ticket implements Runnable {
    private int ticket = 5; 
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            if(this.ticket > 0){
                System.out.println(Thread.currentThread().getName()+"处还有余票:"+(this.ticket--)+"张,i="+i);
            }
        }
    }

    public static void main(String[] args) {
        Ticket t = new Ticket();
        new Thread(t,"张三").start();
        new Thread(t,"李四").start();
        new Thread(t,"王五").start();
    }

}

使用Runnable接口实现多线程,最后还是要用Thread的start()方法启动线程。
图片描述

线程也有优先级,通过setPriority()方法设置,该方法接收一个int型参数。

public class Priority implements Runnable {

    @Override
    public void run() {
        for(int i=1;i<=5;i++){
            System.out.println(Thread.currentThread().getName()+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Priority p = new Priority();
        Thread p1 = new Thread(p,"线程A");
        Thread p2 = new Thread(p,"线程B");
        p1.setPriority(Thread.MAX_PRIORITY);
        p2.setPriority(Thread.MIN_PRIORITY);
        p1.start();
        p2.start();
        new Thread(p,"线程C").start();
    }
}

执行结果是,A的优先级最高,最先执行;B的优先级最低,最后执行。但是真实的执行顺序大致如此,并不绝对。sleep()方法用于让线程休眠,参数的单位是毫秒。
图片描述

2、线程同步和死锁
public class Ticket implements Runnable {
    private int ticket = 5; 
    @Override
    public void run() {
        for(int i=0;i<20;i++){
            synchronized(this){
                if(this.ticket > 0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"处还有余票:"+(this.ticket--)+"张,i="+i);
                }
            }
        }
    }

    public static void main(String[] args) {
        Ticket t = new Ticket();
        new Thread(t,"张三").start();
        new Thread(t,"李四").start();
        new Thread(t,"王五").start();
    }

}

上例使用synchronized代码块进行线程同步(也可在方法前加该关键字构成同步方法),使用同步的好处在于避免产生负票数,保证数据的安全。简单的说同步就是一个线程要等待另一个线程执行完毕,在多个线程访问同一资源时,要考虑同步问题。但过多的同步可能造成死锁。
图片描述

打开App,阅读手记
7人推荐
发表评论
随时随地看视频慕课网APP