java之多线程常用的几个方法汇总

java 专栏收录该内容
36 篇文章 0 订阅

java之多线程常用的几个方法汇总

sleep()

  • sleep()方法属于Thread类,主要作用是让当前线程停止执行,把cpu让给其他线程执行,如果有锁,不会释放锁,等睡眠期满之后,恢复为可运行状态,等到切换为运行状态时继续运行。

  • 线程睡眠到期后自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间,因此,sleep()方法不能保证该线程睡眠到期后就开始执行。

  • Thread.sleep()方法是一个静态方法。

  • java有两种sleep()方法

    • 只有毫秒参数

      sleep(long millis) //1s =1000ms
      
    • 另一个只有纳秒和毫秒

      sleep(long millis,int nanos)
      
  • 代码示例

    //令主线程暂停执行2s
    public class ThreadSeven {
        public static void main(String[] args) throws InterruptedException {
            long start = System.currentTimeMillis();
            Thread.sleep(2000);
            System.out.println("时间间隔为:"+(System.currentTimeMillis()-start));
    
        }
    }
    
  • 执行结果

    时间间隔为:2001 
    

    睡眠只是停止运行的最短时间,故结果会比2000稍多一点

wait(),notify(),notifyAll()

  • wait()属于object类,会释放当前线程,进入等待此对象的等待索定池。比方说,线程A调用Obj.wait(),线程A就会停止运行,而转为等待状态。至于等待多长时间,那就看其他线程是否调用Obj.notify().其优势显而易见,成为多换个线程之间进行通讯的手段。

  • wait()方法与notify()必须要与synchronized(resource)一起使用

  • 调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor(即锁,或者管程),如果有多个,只能唤醒其中的一个。

  • 调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程;

  • 示例代码

    class NumberPrint implements Runnable{
    	private int number;
    	public byte res[];
    	public static int count = 5;
    	public NumberPrint(int number, byte a[]){
    		this.number = number;
    		res = a;
    	}
    	public void run(){
    		synchronized (res){
    			while(count-- > 0){
    				try {
    					res.notify();//唤醒等待res资源的线程,把锁交给线程(该同步锁执行完毕自动释放锁)
    					System.out.println(" "+number);
    					res.wait();//释放CPU控制权,释放res的锁,本线程阻塞,等待被唤醒。
    					System.out.println("------线程"+Thread.currentThread().getName()+"获得锁,wait()后的代码继续运行:"+number);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}//end of while
    			return;
    		}//synchronized
    		
    	}
    }
    public class WaitNotify {
    	public static void main(String args[]){
    		final byte a[] = {0};//以该对象为共享资源
    		new Thread(new NumberPrint((1),a),"1").start();
    		new Thread(new NumberPrint((2),a),"2").start();
    	}
    }
    
    
  • 输出结果

     1
     2
    ------线程1获得锁,wait()后的代码继续运行:1
     1
    ------线程2获得锁,wait()后的代码继续运行:2
     2
    ------线程1获得锁,wait()后的代码继续运行:1
     1
    ------线程2获得锁,wait()后的代码继续运行:2
    
    

join()

  • 线程强行运行完:进程里有主线程和子线程,子线程需要大量的耗时运算,主线程可能会在子线程结束之前结束,但是主线程结束前需要子线程的结果,那么就有硬性要求子线程必须赶在主线程结束之前结束,这时候就需要用到join()方法,即让线程间从并行到串行。

  • 可加毫秒参数,等待时间

  • 代码示例

    public class JoinDisplay implements Runnable {
        private int count;
        public int getCount() {
            return count;
        }
        public void setCount(int count) {
            this.count = count;
        }
        @Override
        public void run() {
            for (int i = 0; i <1000000000 ; i++) {
                count++;
            }
        }
    }
    
    public class ThreadSeven {
        public static void main(String[] args) throws InterruptedException {
                 JoinDisplay joinDisplay =new JoinDisplay();
                 Thread thread = new Thread(joinDisplay);//Runnable接口实现 运行原理
                 thread.start();
                 thread.join();
            System.out.println(joinDisplay.getCount());
    
        }
    }
    
  • 运行结果

    1000000000
    
  • 代码二

    public class SimpleWN {
        public static int count = 0;
    
        public static class one implements Runnable {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    synchronized (this) {
                        count++;
                        System.out.println(Thread.currentThread().getName());
                    }
                }
            }
        }
        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(new one());
            Thread t2 = new Thread(new one());
            t1.start();
            t1.join();
            t2.start();
            t2.join();
            System.out.println(count);
        }
    }
    
  • 运行结果

    ....
    Thread-1
    Thread-1
    Thread-1
    20000
    

yield()

  • yield是放弃屈服的意思,一个线程调用yield()意味着告诉虚拟机自己非常乐于助人,可以把自己的位置让给其他线程。当前线程让出cpu后,还会进行cpu资源争夺,能不能再次分配到,就不一定了。

  • 示例代码

    public class YieldDisplay implements Runnable {
    
        private String name;
    
        public YieldDisplay(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
    
            for (int i = 0; i <10 ; i++) {
                System.out.println(this.getName()+i);
                if(i==5){
                    Thread.yield();
                }
    
            }
    
        }
    }
    
    public class ThreadTest {
        public static void main(String[] args) {
        YieldDisplay yieldDisplay = new YieldDisplay("小花");
        YieldDisplay yieldDisplay1 = new YieldDisplay("小草");
        Thread t1 =new Thread(yieldDisplay);
        Thread t2 = new Thread(yieldDisplay1);
        t1.start();
        t2.start();
        }
    }
    

  • 执行结果

    小花0
    小草0
    小草1
    小草2
    小草3
    小草4
    小花1
    小草5
    小花2
    小花3
    

  • 0
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值