java线程

扫码查看

线程

串行单线程执行

在食堂打饭的时候,食堂安排一个打饭大妈打饭,所有同学都排成一个队形,打饭大妈相当于线程,同学打饭相当于任务,这种一个大妈给一群站好队形的同同学打饭相当于java中的单线程串行执行任务。

串行执行的缺点很明显,当一个同学选菜慢的情况下,效率低下,后面的同学早已不耐烦了

并行多线程执行

为了解决上述问题,食堂打算聘请和学生数目一样多的打饭大妈,同时给同学打饭,这样的话同学倒是开心了,很快就能吃上饭,但是食堂承受不了了,因为食堂需要开更多的打饭窗口以及给大妈的工资,映射到多线程中也一样,如果每个任务都创建一个线程来处理的话,任务数量一旦多了,内存就会有很大的负担,甚至可能宕机。

线程池

为了解决上述问题,食堂又做了改进,就是先确定好打饭大妈的数量,然后让同学们排队,每个打饭大妈打完一次饭就叫队列中的下一个。映射到java中我们创建指定数量的线程,然后把任务放到一个队列中去处理,当每个线程处理完任务后就会去队列中取下一个任务处理,可以把线程重复利用,因为线程的创建也是消耗资源的。

所以结论就是:在一定范围内增加线程数量的确可以提升系统的处理能力,但是过多的创建线程将会降低系统的处理速度,如果无限制的创建线程,将会使系统崩溃。


对于一个程序,默认只有一个进程,按照一定的顺序进行操作
但是,如果对一个事件操作很慢,但是cpu内存又足够大去对另一个事件操作
就需要进行并事件操作,也就是多进程,同时操作不同的事件,节省了时间,使得cpu在同样的时间里完成更多的事件

线程的实现

线程实现有两种方法

  • 继承Thread类,重写run()方法
  • 实现Runnable接口,实现run()方法

几个重要的函数

继承Thread

package Experiment;

public class E13{
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start();

        MyThread t2 = new MyThread();
        t2.start();
    }
}
class MyThread extends Thread{
    public void run(){
        for(int i=1;i<20;i++){
            System.out.println(Thread.currentThread().getName()+"-->"+i);
        }
    }
}

输出

Thread-0-->1
Thread-1-->1
Thread-0-->2
Thread-1-->2
Thread-0-->3
Thread-1-->3
Thread-1-->4
Thread-1-->5
Thread-0-->4
Thread-1-->6
Thread-1-->7
Thread-0-->5
Thread-1-->8
Thread-1-->9
Thread-0-->6
Thread-1-->10
Thread-0-->7
Thread-1-->11
Thread-0-->8
Thread-1-->12
Thread-0-->9
Thread-1-->13
Thread-0-->10
Thread-1-->14
Thread-0-->11
Thread-1-->15
Thread-0-->12
Thread-1-->16
Thread-0-->13
Thread-1-->17
Thread-1-->18
Thread-0-->14
Thread-1-->19
Thread-0-->15
Thread-1-->20
Thread-0-->16
Thread-0-->17
Thread-0-->18
Thread-0-->19
Thread-0-->20

可以发现有40条记录,线程0是e1线程,线程1是e2线程
他们是同时进行操作的

Runnable接口

package Experiment;

public class E13{
    public static void main(String[] args) {
        Thread t3 = new Thread(new Task());
        t3.start();

        Thread t4 = new Thread(new Task());
        t4.start();
    }
}
class Task implements Runnable{
    public void run() {
        for(int i=1;i<=20;i++) {
                System.out.println(Thread.currentThread().getName()+"-->"+i);
        }
    }
}

输出

Thread-1-->1
Thread-0-->1
Thread-1-->2
Thread-0-->2
Thread-1-->3
Thread-0-->3
Thread-1-->4
Thread-0-->4
Thread-1-->5
Thread-0-->5
Thread-1-->6
Thread-0-->6
Thread-1-->7
Thread-0-->7
Thread-1-->8
Thread-0-->8
Thread-1-->9
Thread-0-->9
Thread-1-->10
Thread-0-->10
Thread-1-->11
Thread-0-->11
Thread-1-->12
Thread-0-->12
Thread-1-->13
Thread-0-->13
Thread-0-->14
Thread-0-->15
Thread-0-->16
Thread-1-->14
Thread-1-->15
Thread-1-->16
Thread-1-->17
Thread-1-->18
Thread-1-->19
Thread-1-->20
Thread-0-->17
Thread-0-->18
Thread-0-->19
Thread-0-->20

发现Runnable接口和继承Thread的效果差不多

区别

①由于Java不允许多继承,所以继承了Thread类,就不能继承其他类,而Runnable接口可以继续接其他接口
②实现Runnable接口的线程类的多个线程,适合访问同一变量,而Thread不能(多窗口买票问题)
③Thread采用了Runnable接口

比如

package Experiment;

public class E13{
    public static void main(String[] args) {
        MyThread t=new MyThread();//只能使用同一个t
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }
}

class MyThread implements Runnable{
    private int ticket=100;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            if(ticket>0){
                System.out.println(Thread.currentThread().getName()+"...is saling,余票:"+ticket--);
            }
        }
    }
}

输出

Thread-0...is saling,余票:100
Thread-2...is saling,余票:98
Thread-2...is saling,余票:95
Thread-1...is saling,余票:99
Thread-2...is saling,余票:94
Thread-0...is saling,余票:97
Thread-3...is saling,余票:96
Thread-0...is saling,余票:91
Thread-2...is saling,余票:92
Thread-1...is saling,余票:93
Thread-2...is saling,余票:88
Thread-2...is saling,余票:86
Thread-2...is saling,余票:85
Thread-0...is saling,余票:89
Thread-3...is saling,余票:90
Thread-0...is saling,余票:83
Thread-2...is saling,余票:84
Thread-1...is saling,余票:87
Thread-2...is saling,余票:80
Thread-0...is saling,余票:81
Thread-3...is saling,余票:82
Thread-0...is saling,余票:77
Thread-2...is saling,余票:78
Thread-1...is saling,余票:79
Thread-2...is saling,余票:74
Thread-0...is saling,余票:75
Thread-3...is saling,余票:76
Thread-0...is saling,余票:71
Thread-2...is saling,余票:72
Thread-1...is saling,余票:73
Thread-2...is saling,余票:68
Thread-0...is saling,余票:69
Thread-3...is saling,余票:70
Thread-0...is saling,余票:65
Thread-2...is saling,余票:66
Thread-1...is saling,余票:67
Thread-2...is saling,余票:62
Thread-2...is saling,余票:60
Thread-0...is saling,余票:63
Thread-3...is saling,余票:64
Thread-3...is saling,余票:57
Thread-0...is saling,余票:58
Thread-2...is saling,余票:59
Thread-1...is saling,余票:61
Thread-2...is saling,余票:54
Thread-0...is saling,余票:55
Thread-3...is saling,余票:56
Thread-0...is saling,余票:51
Thread-2...is saling,余票:52
Thread-1...is saling,余票:53
Thread-2...is saling,余票:48
Thread-0...is saling,余票:49
Thread-3...is saling,余票:50
Thread-0...is saling,余票:45
Thread-2...is saling,余票:46
Thread-1...is saling,余票:47
Thread-2...is saling,余票:42
Thread-0...is saling,余票:43
Thread-3...is saling,余票:44
Thread-0...is saling,余票:39
Thread-2...is saling,余票:40
Thread-1...is saling,余票:41
Thread-2...is saling,余票:36
Thread-0...is saling,余票:37
Thread-3...is saling,余票:38
Thread-0...is saling,余票:33
Thread-2...is saling,余票:34
Thread-1...is saling,余票:35
Thread-2...is saling,余票:30
Thread-0...is saling,余票:31
Thread-3...is saling,余票:32
Thread-0...is saling,余票:27
Thread-2...is saling,余票:28
Thread-1...is saling,余票:29
Thread-2...is saling,余票:24
Thread-0...is saling,余票:25
Thread-3...is saling,余票:26
Thread-0...is saling,余票:21
Thread-2...is saling,余票:22
Thread-1...is saling,余票:23
Thread-2...is saling,余票:18
Thread-0...is saling,余票:19
Thread-0...is saling,余票:15
Thread-3...is saling,余票:20
Thread-0...is saling,余票:14
Thread-2...is saling,余票:16
Thread-1...is saling,余票:17
Thread-2...is saling,余票:11
Thread-0...is saling,余票:12
Thread-3...is saling,余票:13
Thread-0...is saling,余票:8
Thread-2...is saling,余票:9
Thread-1...is saling,余票:10
Thread-2...is saling,余票:5
Thread-0...is saling,余票:6
Thread-3...is saling,余票:7
Thread-3...is saling,余票:1
Thread-0...is saling,余票:2
Thread-2...is saling,余票:3
Thread-1...is saling,余票:4

可以发现这100条是一起操作的,没有重复

而对于继承

package Experiment;

public class E13{
    public static void main(String[] args) {
        MyThread t=new MyThread();//只能使用同一个t

        //10个线程
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
    }
}

class MyThread extends Thread{
    private int ticket=10;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            if(ticket>0){
                System.out.println(Thread.currentThread().getName()+"...is saling,余票:"+ticket--);
            }
        }
    }
}

输出

Thread-2...is saling,余票:10
Thread-3...is saling,余票:10
Thread-1...is saling,余票:10
Thread-1...is saling,余票:9
Thread-4...is saling,余票:10
Thread-3...is saling,余票:9
Thread-2...is saling,余票:9
Thread-3...is saling,余票:8
Thread-4...is saling,余票:9
Thread-1...is saling,余票:8
Thread-4...is saling,余票:8
Thread-3...is saling,余票:7
Thread-2...is saling,余票:8
Thread-3...is saling,余票:6
Thread-4...is saling,余票:7
Thread-1...is saling,余票:7
Thread-4...is saling,余票:6
Thread-3...is saling,余票:5
Thread-2...is saling,余票:7
Thread-3...is saling,余票:4
Thread-4...is saling,余票:5
Thread-1...is saling,余票:6
Thread-4...is saling,余票:4
Thread-3...is saling,余票:3
Thread-2...is saling,余票:6
Thread-3...is saling,余票:2
Thread-4...is saling,余票:3
Thread-1...is saling,余票:5
Thread-4...is saling,余票:2
Thread-4...is saling,余票:1
Thread-3...is saling,余票:1
Thread-2...is saling,余票:5
Thread-2...is saling,余票:4
Thread-2...is saling,余票:3
Thread-2...is saling,余票:2
Thread-2...is saling,余票:1
Thread-1...is saling,余票:4
Thread-1...is saling,余票:3
Thread-1...is saling,余票:2
Thread-1...is saling,余票:1

每个线程是独立的
只是在同一时间完成4个线程而已

如果加了synchronized (this),那么两者都可以实现资源共享了

但既然Thread是采用了Runnable接口,那么Thread有什么好处,为什么创建Thread ?

12-28 05:01
查看更多