Java多线程

什么是线程

   要了解线程,要先了解进程

    -进程

      进程是指可执行程序并存放在计算机存储器的一个指令序列,它是一个动态执行的过程。(平时:)

   -线程

      线程是比进程还要小的运行单位,一个进程包含多个线程。(线程可以看成是一个子程序)

线程的创建  

    -法一:创建一个Thread类(位于java.lang包下),或者一个Thread子类(自定义线程类可直接继承Thread)的对象。

    -法二:创建一个实现Runnable接口的类的对象。

  Thread类的常用方法

方法

说明
public void run() 线程相关的代码写在该方法中,一般需要重写
public void start() 启动线程的方法
public static void sleep(long m) 线程休眠m毫秒的方法
public void join() 优先执行调用join()方法的线程

  Runnable接口

    -只有一个方法run();

    -Runnable是Java中用以实现线程的接口

    -任何 实现线程功能的类都必须实现该接口

  通过Thread类创建线程

    简单介绍线程

package Thread;
class MyThread extends Thread{
    public void run(){
        System.out.println(getName()+"该线程正在执行");
    }
}
public class ThreadTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
//        System.out.println("主线程1");
        MyThread mt=new MyThread();
        mt.start();//启动线程,每个线程只能启动一次
//        mt.start();//without compile error.But run error
//        System.out.println("主线程2");

    }

}

    复杂线程

package Thread;
class MyThread2 extends Thread{
    public MyThread2(String name){
        super(name);
    }
    public void run(){
        for(int i=1;i<=10;i++)
            System.out.println(getName()+"正在执行第"+i+"次");
    }
}
public class ThreadTest2 {
    public static void main(String[] args){
        
    MyThread2 one=new MyThread2("线程1");
    MyThread2 two=new MyThread2("线程2");
    one.start();
    two.start();
    }
}

   线程的运行时随机的,因为我们不知道它什么时候获得CPU的使用权限,因此线程运行的结果也是随机的。

  通过实现Runnable接口的方式创建

    为什么要实现Runnable接口?

    -Java不支持多继承,如果类已继承一个类就不能再继承Thread

    -不打算重写Thread类的其他方法

    例子一:

  

package Runnable;
class PrintRunnable implements Runnable{
   public void run() {
int i=1;
while(i<=10)
System.out.println(Thread.currentThread().getName()+"正在运行"+(i++)+"次"); 
}
}

public class Test {

/** * @param args */

public static void main(String[] args
) {
// TODO Auto-generated method stub PrintRunnable test=new PrintRunnable(); Thread t1=new Thread(test); t1.start(); PrintRunnable test2=new PrintRunnable(); Thread t2=new Thread(test2); t2.start(); } }

    例一运行结果:

Thread-0正在运行1次
Thread-0正在运行2次
Thread-0正在运行3次
Thread-0正在运行4次
Thread-0正在运行5次
Thread-0正在运行6次
Thread-0正在运行7次
Thread-0正在运行8次
Thread-0正在运行9次
Thread-0正在运行10次
Thread-1正在运行1次
Thread-1正在运行2次
Thread-1正在运行3次
Thread-1正在运行4次
Thread-1正在运行5次
Thread-1正在运行6次
Thread-1正在运行7次
Thread-1正在运行8次
Thread-1正在运行9次
Thread-1正在运行10次

 

    例2

package Runnable;
class PrintRunnable implements Runnable{
    int i=1;
    public void run() {
    
        while(i<=10)
        System.out.println(Thread.currentThread().getName()+"正在运行"+(i++)+"次");
        
    }
    
}
public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        PrintRunnable test=new PrintRunnable();
        Thread t1=new Thread(test);
        t1.start();
//        PrintRunnable test2=new PrintRunnable();
        Thread t2=new Thread(test);
        //这里将Thread的test2转换成test,也是可以的
        //Thread t2=new Thread(test);
        t2.start();
    }

}

  例二运行结果

Thread-0正在运行1次
Thread-1正在运行2次
Thread-0正在运行3次
Thread-1正在运行4次
Thread-0正在运行5次
Thread-1正在运行6次
Thread-0正在运行7次
Thread-1正在运行8次
Thread-0正在运行9次
Thread-1正在运行10次

   从运行结果可以看到,在这里线程1和线程2公用了同一个代码i。适合于多个线程处理同一个资源。

线程的状态

   -新建(New):创建Thread或者Thread的子类时,线程处于新建状态。

   -可运行(Runnable):当调用star()方法时,线程获取CPU使用权前的状态。

   -正在进行(Running):获取CPU使用权后的状态,调用yield()方法,可以从正在运行状态进入到可运行状态或者当时间片用完时,也会重新进入可运行状态等待获取CPU使用权限。

   -阻塞(Blocked):线程遇到干扰后(正在运行状态时可调用Thread类当中的方法,如join()、wait()、sleep()、I/O请求,进入阻塞状态。相反阻塞状态无法直接进入正在运行状态,但是当(1)等待调用join()的线程执行完毕或者(2)调用notify()或notifyAll()或(3)sleep超时或(4)I/O请求完成后,可以进入可运行状态),无法执行的状态。

   -终止(Dead):终止。

线程的生命周期

123

   -sleep方法应用

    Thread类的方法:public static void sleep(long millis),millis表示毫秒

    作用:在指定的毫秒数内让正在执行的线程休眠(暂停执行)

       参数为休眠的时间,单位是毫秒

    例子:

package Thread;

class MyThread3 implements Runnable{

    public void run() {
        for(int i=1;i<=15;i++){
            System.out.println(Thread.currentThread().getName()+"正在运行第"+i+"次");
            //当我们想一秒钟实现一次输出可以调用Thread类中的sleep
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                //当我们运行该代码块时,被打断将出现异常
                e.printStackTrace();
            }
        }
        
    }
    
}



public class SleepDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        MyThread3 mt=new MyThread3();
        Thread t=new Thread(mt);
        t.start();
    }

}

    作用:当我们想实现计时功能或定期刷新某数据时,可以调用sleep方法。但是有一点需要注意,当我们调用完sleep方法后,系统是不会进入正在运行状态,而是进入可运行状态等待获取CPU权限,因此,当我们用该方法写时钟时,是有一定的误差,会发现时间越走越慢。sleep方法适用于时间要求不太精确的状况。

    例二:

package Thread;

class MyThread3 implements Runnable{

    public void run() {
        for(int i=1;i<=15;i++){
            System.out.println(Thread.currentThread().getName()+"正在运行第"+i+"次");
            //当我们想一秒钟实现一次输出可以调用Thread类中的sleep
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                //当我们运行该代码块时,被打断将出现异常
                e.printStackTrace();
            }
        }
        
    }
    
}



public class SleepDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        MyThread3 mt=new MyThread3();
        Thread t=new Thread(mt);
        t.start();
        Thread t1=new Thread(mt);
        t1.start();
    }

}

 运行结果:

Thread-0正在运行第1次
Thread-1正在运行第1次
Thread-1正在运行第2次
Thread-0正在运行第2次
Thread-0正在运行第3次
Thread-1正在运行第3次
Thread-0正在运行第4次
Thread-1正在运行第4次
Thread-0正在运行第5次
Thread-1正在运行第5次
Thread-0正在运行第6次
Thread-1正在运行第6次
Thread-0正在运行第7次
Thread-1正在运行第7次
Thread-0正在运行第8次
Thread-1正在运行第8次
Thread-0正在运行第9次
Thread-1正在运行第9次
Thread-0正在运行第10次
Thread-1正在运行第10次
Thread-0正在运行第11次
Thread-1正在运行第11次
Thread-0正在运行第12次
Thread-1正在运行第12次
Thread-0正在运行第13次
Thread-1正在运行第13次
Thread-0正在运行第14次
Thread-1正在运行第14次
Thread-0正在运行第15次
Thread-1正在运行第15次

     当有多个线程同时执行时,我们可以发现它是两个线程交替工作的,同时谁先执行也仍具有随机性。当线程1执行完之后,将进入休眠期,此期间,线程2有更大的机会去获取CPU的使用权限,那如果当线程2未获取使用权限而线程1“苏醒后”又要获取CPU权限,这时候怎么办?

   -join方法应用

    Thread类的方法:public final void join()

    作用:等待调用该方法的线程结束后才能执行。当一个线程调用join()方法后,它会优先执行,只有先执行完它之后才会执行别的线程。因此他是一种抢占资源的方法。

  

package Thread;
class MyThread4 extends Thread{
    public void run(){
        for(int i=1;i<=15;i++)
        System.out.println(getName()+"正在执行"+i);
        
    }
}
public class JoinDemo {
    public static void main(String[] args){
        MyThread4 mt=new MyThread4();
        mt.start();
        try {
            mt.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for(int i=1;i<=18;i++)
        System.out.println("主线程执行完毕"+i);
    }
}

运行结果:

Thread-0正在执行1
Thread-0正在执行2
Thread-0正在执行3
Thread-0正在执行4
Thread-0正在执行5
Thread-0正在执行6
Thread-0正在执行7
Thread-0正在执行8
Thread-0正在执行9
Thread-0正在执行10
Thread-0正在执行11
Thread-0正在执行12
Thread-0正在执行13
Thread-0正在执行14
Thread-0正在执行15
主线程执行完毕1
主线程执行完毕2
主线程执行完毕3
主线程执行完毕4
主线程执行完毕5
主线程执行完毕6
主线程执行完毕7
主线程执行完毕8
主线程执行完毕9
主线程执行完毕10
主线程执行完毕11
主线程执行完毕12
主线程执行完毕13
主线程执行完毕14
主线程执行完毕15
主线程执行完毕16
主线程执行完毕17
主线程执行完毕18

     通过运行结果我们可以发现,mt线程调用了join()方法之后,不管运行多少次他都是优先执行的。

   Thread类的方法:public final void join(long millis)

   作用:等待该线程终止的最长时间为millis毫秒。当millis=1000,当调用join()方法后,mt执行了1000毫秒,不管mt方法是否执行完毕,系统都会执行下一个线程。  

   例子:

package Thread;
class MyThread4 extends Thread{
    public void run(){
        for(int i=1;i<=300;i++)
        System.out.println(getName()+"正在执行"+i);
        
    }
}
public class JoinDemo {
    public static void main(String[] args){
        MyThread4 mt=new MyThread4();
        mt.start();
        try {
            mt.join(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for(int i=1;i<=18;i++)
        System.out.println("主线程执行完毕"+i);
    }
}

   运行结果:

Thread-0正在执行1
Thread-0正在执行2
Thread-0正在执行3
Thread-0正在执行4
Thread-0正在执行5
Thread-0正在执行6
Thread-0正在执行7
Thread-0正在执行8
Thread-0正在执行9
Thread-0正在执行10
Thread-0正在执行11
Thread-0正在执行12
Thread-0正在执行13
Thread-0正在执行14
Thread-0正在执行15
Thread-0正在执行16
Thread-0正在执行17
Thread-0正在执行18
Thread-0正在执行19
Thread-0正在执行20
Thread-0正在执行21
Thread-0正在执行22
Thread-0正在执行23
Thread-0正在执行24
Thread-0正在执行25
Thread-0正在执行26
Thread-0正在执行27
Thread-0正在执行28
Thread-0正在执行29
Thread-0正在执行30
Thread-0正在执行31
主线程执行完毕1
主线程执行完毕2
主线程执行完毕3
主线程执行完毕4
主线程执行完毕5
主线程执行完毕6
主线程执行完毕7
主线程执行完毕8
主线程执行完毕9
Thread-0正在执行32
主线程执行完毕10
Thread-0正在执行33
主线程执行完毕11
主线程执行完毕12
Thread-0正在执行34
主线程执行完毕13
Thread-0正在执行35
主线程执行完毕14
主线程执行完毕15
主线程执行完毕16
Thread-0正在执行36
主线程执行完毕17
Thread-0正在执行37
主线程执行完毕18
Thread-0正在执行38
主线程执行完毕19
Thread-0正在执行39
主线程执行完毕20
Thread-0正在执行40
主线程执行完毕21
Thread-0正在执行41
主线程执行完毕22
Thread-0正在执行42
主线程执行完毕23
Thread-0正在执行43
主线程执行完毕24
Thread-0正在执行44
主线程执行完毕25
Thread-0正在执行45
主线程执行完毕26
Thread-0正在执行46
主线程执行完毕27
Thread-0正在执行47
主线程执行完毕28
Thread-0正在执行48
主线程执行完毕29
Thread-0正在执行49
主线程执行完毕30
Thread-0正在执行50
主线程执行完毕31
Thread-0正在执行51
主线程执行完毕32
Thread-0正在执行52
主线程执行完毕33
Thread-0正在执行53
主线程执行完毕34
Thread-0正在执行54
主线程执行完毕35
Thread-0正在执行55
主线程执行完毕36
Thread-0正在执行56
主线程执行完毕37
Thread-0正在执行57
主线程执行完毕38
Thread-0正在执行58
主线程执行完毕39
Thread-0正在执行59
主线程执行完毕40
Thread-0正在执行60
主线程执行完毕41
Thread-0正在执行61
主线程执行完毕42
Thread-0正在执行62
主线程执行完毕43
主线程执行完毕44
Thread-0正在执行63
主线程执行完毕45
Thread-0正在执行64
主线程执行完毕46
Thread-0正在执行65
主线程执行完毕47
Thread-0正在执行66
主线程执行完毕48
Thread-0正在执行67
主线程执行完毕49
Thread-0正在执行68
Thread-0正在执行69
Thread-0正在执行70
Thread-0正在执行71
Thread-0正在执行72
Thread-0正在执行73
Thread-0正在执行74
主线程执行完毕50
Thread-0正在执行75
主线程执行完毕51
Thread-0正在执行76
主线程执行完毕52
Thread-0正在执行77
主线程执行完毕53
Thread-0正在执行78
主线程执行完毕54
主线程执行完毕55
主线程执行完毕56
主线程执行完毕57
Thread-0正在执行79
Thread-0正在执行80
Thread-0正在执行81
主线程执行完毕58
Thread-0正在执行82
主线程执行完毕59
Thread-0正在执行83
主线程执行完毕60
Thread-0正在执行84
主线程执行完毕61
Thread-0正在执行85
主线程执行完毕62
Thread-0正在执行86
主线程执行完毕63
Thread-0正在执行87
主线程执行完毕64
Thread-0正在执行88
主线程执行完毕65
Thread-0正在执行89
主线程执行完毕66
Thread-0正在执行90
主线程执行完毕67
Thread-0正在执行91
主线程执行完毕68
Thread-0正在执行92
主线程执行完毕69
Thread-0正在执行93
主线程执行完毕70
Thread-0正在执行94
主线程执行完毕71
Thread-0正在执行95
主线程执行完毕72
Thread-0正在执行96
主线程执行完毕73
Thread-0正在执行97
主线程执行完毕74
Thread-0正在执行98
主线程执行完毕75
Thread-0正在执行99
主线程执行完毕76
Thread-0正在执行100
主线程执行完毕77
Thread-0正在执行101
主线程执行完毕78
Thread-0正在执行102
主线程执行完毕79
Thread-0正在执行103
主线程执行完毕80
Thread-0正在执行104
主线程执行完毕81
Thread-0正在执行105
主线程执行完毕82
Thread-0正在执行106
主线程执行完毕83
Thread-0正在执行107
主线程执行完毕84
Thread-0正在执行108
主线程执行完毕85
Thread-0正在执行109
主线程执行完毕86
Thread-0正在执行110
主线程执行完毕87
Thread-0正在执行111
主线程执行完毕88
主线程执行完毕89
主线程执行完毕90
主线程执行完毕91
主线程执行完毕92
主线程执行完毕93
主线程执行完毕94
Thread-0正在执行112
主线程执行完毕95
Thread-0正在执行113
主线程执行完毕96
Thread-0正在执行114
主线程执行完毕97
Thread-0正在执行115
主线程执行完毕98
Thread-0正在执行116
主线程执行完毕99
Thread-0正在执行117
主线程执行完毕100
Thread-0正在执行118
主线程执行完毕101
Thread-0正在执行119
主线程执行完毕102
Thread-0正在执行120
主线程执行完毕103
Thread-0正在执行121
主线程执行完毕104
Thread-0正在执行122
主线程执行完毕105
Thread-0正在执行123
主线程执行完毕106
Thread-0正在执行124
主线程执行完毕107
Thread-0正在执行125
主线程执行完毕108
Thread-0正在执行126
主线程执行完毕109
Thread-0正在执行127
主线程执行完毕110
Thread-0正在执行128
主线程执行完毕111
Thread-0正在执行129
主线程执行完毕112
Thread-0正在执行130
主线程执行完毕113
Thread-0正在执行131
主线程执行完毕114
Thread-0正在执行132
主线程执行完毕115
Thread-0正在执行133
主线程执行完毕116
Thread-0正在执行134
主线程执行完毕117
Thread-0正在执行135
主线程执行完毕118
Thread-0正在执行136
主线程执行完毕119
Thread-0正在执行137
主线程执行完毕120
Thread-0正在执行138
Thread-0正在执行139
Thread-0正在执行140
Thread-0正在执行141
主线程执行完毕121
主线程执行完毕122
Thread-0正在执行142
主线程执行完毕123
Thread-0正在执行143
主线程执行完毕124
Thread-0正在执行144
主线程执行完毕125
Thread-0正在执行145
主线程执行完毕126
Thread-0正在执行146
主线程执行完毕127
Thread-0正在执行147
主线程执行完毕128
Thread-0正在执行148
主线程执行完毕129
Thread-0正在执行149
主线程执行完毕130
Thread-0正在执行150
主线程执行完毕131
Thread-0正在执行151
主线程执行完毕132
Thread-0正在执行152
主线程执行完毕133
Thread-0正在执行153
主线程执行完毕134
Thread-0正在执行154
主线程执行完毕135
Thread-0正在执行155
主线程执行完毕136
Thread-0正在执行156
主线程执行完毕137
Thread-0正在执行157
主线程执行完毕138
Thread-0正在执行158
主线程执行完毕139
Thread-0正在执行159
主线程执行完毕140
Thread-0正在执行160
主线程执行完毕141
Thread-0正在执行161
Thread-0正在执行162
Thread-0正在执行163
Thread-0正在执行164
Thread-0正在执行165
Thread-0正在执行166
Thread-0正在执行167
Thread-0正在执行168
Thread-0正在执行169
Thread-0正在执行170
Thread-0正在执行171
Thread-0正在执行172
Thread-0正在执行173
主线程执行完毕142
主线程执行完毕143
主线程执行完毕144
主线程执行完毕145
Thread-0正在执行174
Thread-0正在执行175
Thread-0正在执行176
Thread-0正在执行177
Thread-0正在执行178
主线程执行完毕146
Thread-0正在执行179
主线程执行完毕147
Thread-0正在执行180
主线程执行完毕148
Thread-0正在执行181
主线程执行完毕149
Thread-0正在执行182
主线程执行完毕150
Thread-0正在执行183
主线程执行完毕151
Thread-0正在执行184
主线程执行完毕152
Thread-0正在执行185
主线程执行完毕153
Thread-0正在执行186
主线程执行完毕154
Thread-0正在执行187
主线程执行完毕155
Thread-0正在执行188
主线程执行完毕156
Thread-0正在执行189
主线程执行完毕157
Thread-0正在执行190
主线程执行完毕158
Thread-0正在执行191
主线程执行完毕159
Thread-0正在执行192
主线程执行完毕160
Thread-0正在执行193
主线程执行完毕161
Thread-0正在执行194
主线程执行完毕162
Thread-0正在执行195
主线程执行完毕163
Thread-0正在执行196
主线程执行完毕164
Thread-0正在执行197
主线程执行完毕165
Thread-0正在执行198
主线程执行完毕166
Thread-0正在执行199
主线程执行完毕167
Thread-0正在执行200
主线程执行完毕168
Thread-0正在执行201
主线程执行完毕169
Thread-0正在执行202
主线程执行完毕170
Thread-0正在执行203
主线程执行完毕171
Thread-0正在执行204
主线程执行完毕172
Thread-0正在执行205
主线程执行完毕173
Thread-0正在执行206
主线程执行完毕174
Thread-0正在执行207
主线程执行完毕175
Thread-0正在执行208
主线程执行完毕176
Thread-0正在执行209
主线程执行完毕177
Thread-0正在执行210
主线程执行完毕178
Thread-0正在执行211
主线程执行完毕179
Thread-0正在执行212
主线程执行完毕180
Thread-0正在执行213
主线程执行完毕181
Thread-0正在执行214
主线程执行完毕182
Thread-0正在执行215
主线程执行完毕183
Thread-0正在执行216
主线程执行完毕184
Thread-0正在执行217
主线程执行完毕185
Thread-0正在执行218
主线程执行完毕186
Thread-0正在执行219
主线程执行完毕187
Thread-0正在执行220
主线程执行完毕188
Thread-0正在执行221
主线程执行完毕189
Thread-0正在执行222
主线程执行完毕190
Thread-0正在执行223
主线程执行完毕191
Thread-0正在执行224
主线程执行完毕192
Thread-0正在执行225
主线程执行完毕193
主线程执行完毕194
主线程执行完毕195
主线程执行完毕196
主线程执行完毕197
主线程执行完毕198
主线程执行完毕199
主线程执行完毕200
主线程执行完毕201
主线程执行完毕202
主线程执行完毕203
主线程执行完毕204
主线程执行完毕205
主线程执行完毕206
主线程执行完毕207
主线程执行完毕208
主线程执行完毕209
主线程执行完毕210
主线程执行完毕211
主线程执行完毕212
Thread-0正在执行226
主线程执行完毕213
Thread-0正在执行227
主线程执行完毕214
Thread-0正在执行228
主线程执行完毕215
Thread-0正在执行229
主线程执行完毕216
Thread-0正在执行230
主线程执行完毕217
Thread-0正在执行231
主线程执行完毕218
Thread-0正在执行232
主线程执行完毕219
Thread-0正在执行233
主线程执行完毕220
Thread-0正在执行234
主线程执行完毕221
Thread-0正在执行235
主线程执行完毕222
Thread-0正在执行236
主线程执行完毕223
Thread-0正在执行237
主线程执行完毕224
Thread-0正在执行238
主线程执行完毕225
主线程执行完毕226
主线程执行完毕227
主线程执行完毕228
主线程执行完毕229
Thread-0正在执行239
主线程执行完毕230
Thread-0正在执行240
主线程执行完毕231
Thread-0正在执行241
主线程执行完毕232
Thread-0正在执行242
主线程执行完毕233
Thread-0正在执行243
主线程执行完毕234
Thread-0正在执行244
主线程执行完毕235
Thread-0正在执行245
主线程执行完毕236
Thread-0正在执行246
主线程执行完毕237
Thread-0正在执行247
主线程执行完毕238
Thread-0正在执行248
主线程执行完毕239
Thread-0正在执行249
主线程执行完毕240
Thread-0正在执行250
主线程执行完毕241
Thread-0正在执行251
主线程执行完毕242
Thread-0正在执行252
主线程执行完毕243
Thread-0正在执行253
主线程执行完毕244
Thread-0正在执行254
主线程执行完毕245
Thread-0正在执行255
主线程执行完毕246
Thread-0正在执行256
Thread-0正在执行257
Thread-0正在执行258
Thread-0正在执行259
主线程执行完毕247
Thread-0正在执行260
主线程执行完毕248
主线程执行完毕249
主线程执行完毕250
主线程执行完毕251
主线程执行完毕252
主线程执行完毕253
主线程执行完毕254
主线程执行完毕255
主线程执行完毕256
主线程执行完毕257
主线程执行完毕258
主线程执行完毕259
Thread-0正在执行261
主线程执行完毕260
Thread-0正在执行262
主线程执行完毕261
Thread-0正在执行263
主线程执行完毕262
Thread-0正在执行264
主线程执行完毕263
Thread-0正在执行265
主线程执行完毕264
Thread-0正在执行266
主线程执行完毕265
Thread-0正在执行267
主线程执行完毕266
Thread-0正在执行268
主线程执行完毕267
Thread-0正在执行269
主线程执行完毕268
Thread-0正在执行270
主线程执行完毕269
Thread-0正在执行271
主线程执行完毕270
Thread-0正在执行272
主线程执行完毕271
Thread-0正在执行273
主线程执行完毕272
主线程执行完毕273
Thread-0正在执行274
Thread-0正在执行275
Thread-0正在执行276
Thread-0正在执行277
主线程执行完毕274
Thread-0正在执行278
主线程执行完毕275
Thread-0正在执行279
主线程执行完毕276
Thread-0正在执行280
主线程执行完毕277
Thread-0正在执行281
主线程执行完毕278
Thread-0正在执行282
主线程执行完毕279
Thread-0正在执行283
主线程执行完毕280
Thread-0正在执行284
主线程执行完毕281
Thread-0正在执行285
主线程执行完毕282
Thread-0正在执行286
主线程执行完毕283
Thread-0正在执行287
主线程执行完毕284
Thread-0正在执行288
主线程执行完毕285
Thread-0正在执行289
主线程执行完毕286
Thread-0正在执行290
主线程执行完毕287
Thread-0正在执行291
主线程执行完毕288
Thread-0正在执行292
主线程执行完毕289
Thread-0正在执行293
主线程执行完毕290
Thread-0正在执行294
主线程执行完毕291
Thread-0正在执行295
主线程执行完毕292
Thread-0正在执行296
主线程执行完毕293
Thread-0正在执行297
主线程执行完毕294
Thread-0正在执行298
主线程执行完毕295
Thread-0正在执行299
主线程执行完毕296
Thread-0正在执行300
主线程执行完毕297
主线程执行完毕298
主线程执行完毕299
主线程执行完毕300

    从运行结果我们可以发现,我们设置millis=1,当mt线程执行到第31次后,线程进入休眠状态但仍未结束,然后执行主线程,此后mt线程和主线程将随机获取CPU的使用权限,继续执行直至线程结束。

线程优先级

   -Java为线程类提供了10个优先级

   -优先级可以同整数1-10表示,超过范围会抛出异常

   -主线程默认优先级为5

   -数字越大,优先级别越高

   -可以使用优先级常量表示优先级

    (1)MAX_PRIORITY:线程的最高优先级10

    (2)MIN_PRIORITY:线程的最低优先级1

    (3)NORM_PRIORITY:线程的默认优先级5

   -优先级相关的方法:

 

方法 说明
public void getPriority() 获取线程优先级的方法
public void setPriority(int newPriority) 设置线程优先级的方法
例子:
package Thread;
class MyThread5 extends Thread{
    private String name;
    public MyThread5(String name){
        this.name=name;
    }
    public void run(){
        for(int i=1;i<=10;i++){
            System.out.println("线程"+name+"正在执行"+i);
        }
    }
}
public class Priority {
    public static void main(String [] args){
        //获取主线程的优先级
        int mainPriority=Thread.currentThread().getPriority();
        System.out.println("主线程的优先级"+mainPriority);
        MyThread5 mt1=new MyThread5("线程1");
        mt1.setPriority(Thread.MAX_PRIORITY);
        mt1.start();
        System.out.println("线程1的优先级"+mt1.getPriority());
        MyThread5 mt2=new MyThread5("线程2");
        mt2.setPriority(1);
        mt2.start();
    }
}

  运行结果:

主线程的优先级5
线程1的优先级10
线程线程1正在执行1
线程线程1正在执行2
线程线程1正在执行3
线程线程1正在执行4
线程线程1正在执行5
线程线程2正在执行1
线程线程1正在执行6
线程线程2正在执行2
线程线程1正在执行7
线程线程2正在执行3
线程线程1正在执行8
线程线程2正在执行4
线程线程1正在执行9
线程线程2正在执行5
线程线程1正在执行10
线程线程2正在执行6
线程线程2正在执行7
线程线程2正在执行8
线程线程2正在执行9
线程线程2正在执行10

    从运行结果我们会发现即使线程1的优先级比主程序优先级高,系统仍会先输出“线程1的优先级为10”,然后再执行线程2,而且,即使线程1比线程2的优先级高,仍有可能在线程1执行的过程中执行线程2。这与系统环境有关!

   多线程运行问题

    -各个线程是通过竞争CPU时间而获得运行机会的

    -各线程什么时候得到CPU时间,占用多久,是不可预测的

    -一个正在运行着的线程在什么地方被暂停是不确定的

线程同步

   -

posted @ 2017-10-09 11:18  乐高战士  阅读(523)  评论(0)    收藏  举报