zoukankan      html  css  js  c++  java
  • java线程

    线程

    串行单线程执行

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

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

    并行多线程执行

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

    线程池

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

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


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

    线程的实现

    线程实现有两种方法

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

    几个重要的函数

    Thread.currentThread().getName()获取当前线程的名字.
    对于线程的名字,如果没有去给他命名,系统自带为他命名
    start()
    启动一个线程

    继承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接口

    第②点的原因是两者的启动方式不同,Runnable线程类是实例化一个对象O后,多次进行new Thread(O).start(),对象,这几个线程属于同一个对象,对象的成员变量是同一个
    而对于Thread线程类启动多个线程需要new MyThread().start();每个线程启动都对应不同的对象,他们的成员变量是独立的
    而如果Thread加了synchronized之后也是可以访问同一个变量的
    所以,只是Thread不适合去访问同一个变量

    从Thread源码中也可以看到,当以Thread方式去实现资源共享时,实际上源码内部是将thread向下转型为了Runnable,实际上内部依然是以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 ?

  • 相关阅读:
    第六章例6-5
    第六章例6-3
    第六章例6-2
    获取JVM默认编码以及获取其它JVM属性的方法(转)
    Java读取文本文件中文乱码问题
    highcharts highstock API js图形
    swing/swt可视化开发工具windowbuilder免费了
    swt 引入 js 问题
    swt 例子
    经验分享:开发SWT应用两点心得(转)
  • 原文地址:https://www.cnblogs.com/Emcikem/p/11892419.html
Copyright © 2011-2022 走看看