Java学习笔记—多线程

Posted 大象踢足球

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习笔记—多线程相关的知识,希望对你有一定的参考价值。

Java线程常用方法总结

1.join()方法

join —— 让一个线程等待另一个线程完成才继续执行。如A线程线程执行体中调用B线程的join()方法,则A线程被阻塞,知道B线程执行完为止,A才能得以继续执行。

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        for(int i=0;i<5;i++){
            System.out.println("main:"+Thread.currentThread().getName() + " " + i);
            if(i==2){
                thread.start();
                thread.join();
            }
        }
    }
}

运行结果:

main:main 0
main:main 1
main:main 2
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
main:main 3
main:main 4

 

2.Thread.sleep()方法

sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,调用sleep 不会释放对象锁。由于没有释放对象锁,所以不能调用里面的同步方法。

public class Main {
    private int j = 10;
    Object obj = new Object();

    public static void main(String[] args) throws InterruptedException {
        Main main = new Main();
        Runnable r1 = main.new MyRunnable();
        Runnable r2 = main.new MyRunnable();
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
    }

    class MyRunnable implements Runnable {
         public void run() {
             synchronized(obj){
                 for (int i = 0; i < 5; i++) {
                     j++;
                     System.out.println("线程:"+Thread.currentThread()+"i:"+i+",j:"+j+",time:"+ System.currentTimeMillis());
                     if(i==2){
                         try {
                             System.out.println("线程:"+Thread.currentThread()+"睡眠");
                             Thread.sleep(2000);
                         } catch (InterruptedException e) {
                             e.printStackTrace();
                         }
                     }
                 }
             }
         }
    }
}

运行结果:

线程:Thread[Thread-0,5,main]i:0,j:11,time:1503114191497
线程:Thread[Thread-0,5,main]i:1,j:12,time:1503114191497
线程:Thread[Thread-0,5,main]i:2,j:13,time:1503114191497
线程:Thread[Thread-0,5,main]睡眠
线程:Thread[Thread-0,5,main]i:3,j:14,time:1503114193500
线程:Thread[Thread-0,5,main]i:4,j:15,time:1503114193500
线程:Thread[Thread-1,5,main]i:0,j:16,time:1503114193500
线程:Thread[Thread-1,5,main]i:1,j:17,time:1503114193500
线程:Thread[Thread-1,5,main]i:2,j:18,time:1503114193501
线程:Thread[Thread-1,5,main]睡眠
线程:Thread[Thread-1,5,main]i:3,j:19,time:1503114195502
线程:Thread[Thread-1,5,main]i:4,j:20,time:1503114195502

从结果看,Thread-0休眠后没有释放锁,所以Thread-1并没有执行,直到Thread-0休眠结束并执行完毕后Thread-1才开始执行。

 

3.Thread.yield( )方法

调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁。但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。

注意,调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Main main = new Main();
        Thread t1 = main.new MyThread();
        t1.start();
    }

    class MyThread extends Thread{
        public void run() {
            long beginTime=System.currentTimeMillis();
            int count=0;
            for (int i=0;i<50000000;i++){
                count=count+(i+1);
                Thread.yield();
            }
            long endTime=System.currentTimeMillis();
            System.out.println("用时:"+(endTime-beginTime)+" 毫秒!");
        }
    }
}

运行结果:

用时:4448 毫秒!

把Thread.yield();注释掉,运行结果:

用时:1 毫秒!

 

4.getPriority和setPriority

用来获取和设置线程优先级。

Thread t1 = new Thread();
t1.setPriority(Thread.MAX_PRIORITY);

MAX_PRIORITY:10

MIN_PRIORITY:1

NORM_PRIORITY:5

 

5.setDaemon和isDaemon

用来设置线程是否成为守护线程和判断线程是否是守护线程。

Thread t1 = new Thread();
t1.setDaemon(true);

守护线程(后台线程)主要是为其他线程提供服务。如JVM中的垃圾回收线程。

守护线程的生命周期与前台线程生命周期有一定关联。主要体现在:当所有的前台线程都进入死亡状态时,后台线程会自动死亡。

以上是关于Java学习笔记—多线程的主要内容,如果未能解决你的问题,请参考以下文章

Java学习笔记—多线程

毕向东Java视频学习笔记Day11-Day13 多线程

尚硅谷_Java零基础教程(多线程)-- 学习笔记

多线程Java多线程学习笔记 | 多线程基础知识

Java学习笔记—多线程(同步容器和并发容器)

Java多线程学习笔记— “Lambda表达式”