文档章节

Java多线程yield,wait,notify,notifyall,join守护线程的区别

IamOkay
 IamOkay
发布于 2014/11/12 08:14
字数 957
阅读 39
收藏 2

参考:http://dylanxu.iteye.com/blog/1322066

          http://zhangjunhd.blog.51cto.com/113473/71387

          http://home.51.com/liuchao197/diary/item/10036456.html

          http://www.open-open.com/lib/view/open1371741636171.html

yied

使得线程从运行态转为就绪态,使得当前线程把运行权交给高于或者和自己同等优先级的线程(包括自己,因为运行原理是当前线程会先去检查其他线程的优先级,如果低于自己,当前线程并不让出执行权),正常情况下,调用yied会等待一会儿,类似于sleep(注:这里的类似是效果类似,原理确实完全不同),同样有一点和sleep相似的是,如果该方法调用在同步方法中,那么该方法不会让出锁资源。

package com.tester.thread.safe;
public class Test extends Thread{
	public YieldTest(){
		
	}
	public Test(String name){
		super(name);
	}
	@Override
	public  void run() {
	     for(int i=0;i<=50;i++){
		System.out.println(""+this.getName()+"-----"+i);
		 if(i==30){
		      this.yield();//让给和自己同等优先级的(包括自己)
		      System.out.println("==>"+this.getName()+"----------------"+i);//1
		   }
		}
       
	}
	public  static void main(String[] args) {
	  Test yt1=new Test("High"); 
	  Test yt2=new Test("low");
          yt1.setPriority(Thread.MAX_PRIORITY); //明显优先级高的获得机会越大
          yt1.start();
          yt2.setPriority(Thread.MIN_PRIORITY); //2  
	  yt2.start();
	}
}

为了测试能不能释放锁资源,可以修改成如下,这里无论优先级如何修改,执行权永远不会让出。

@Override
	public  void run() {
		synchronized (Test.class) { //为什么是这个呢,因为类Class具有共享性
			  for(int i=0;i<=50;i++){
		           System.out.println(""+this.getName()+"-----"+i);
		           if(i==30){
		           this.yield();//让给和自己同等优先级的(包括自己)
		           System.out.println("==>"+this.getName()+"----------------"+i);//1
		          }
			 }
		}
       
	}

sleep.

在没有同步机制的情况下,Sleep是让线程睡眠一会儿,其他线程才有机会执行,如果有同步机制,那么锁资源不会释放

(2).Thread.sleep(long millis),必须带有一个时间参数。 
    sleep(long)使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行; 
    sleep(long)可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会; 
    sleep(long)是不会释放锁标志的。

可将上面的线程中的yied改为sleep进行测试,这里请读者手动一下。

补充一点.sleep方法使用起来控制定时任务并不好,建议使用TimeUnit的使用

  TimeUnit.DAYS.sleep(timeout);
	  TimeUnit.SECONDS.sleep(timeout);
	  TimeUnit.MINUTES.sleep(timeout);

wait

等待一下,注意,同notify/notifyall一样,必须在同步代码块中才能使用,而且该锁必须是当前对象或者当前对象的成员才行。否则触发

public class IllegalMonitorStateExceptionextends RuntimeException

wait和notity只锁住当前对象this.或者this.property,说明该机制的同步并不是由锁来实现的,只能说明当前任务有锁来实现,二wait的让出和notify的通知才是多线程同步的基础。

class Athlete implements Runnable {
    private final int id;
    private Game game;

    public Athlete(int id, Game game) {
      this.id = id;
      this.game = game;
    }

    public boolean equals(Object o) {
      if (!(o instanceof Athlete))
        return false;
      Athlete athlete = (Athlete) o;
      return id == athlete.id;
    }

    public String toString() {
      return "Athlete<" + id + ">";
    }

    public int hashCode() {
      return new Integer(id).hashCode();
    }

    public void run() {
      try {
        game.prepare(this);
      } catch (InterruptedException e) {
        System.out.println(this + " quit the game");
      }
    }
  }

public class Game implements Runnable {
    private Set<Athlete> players = new HashSet<Athlete>();
    private boolean start = false;

    public void addPlayer(Athlete one) {
      players.add(one);
    }

    public void removePlayer(Athlete one) {
      players.remove(one);
    }

    public Collection<Athlete> getPlayers() {
      return Collections.unmodifiableSet(players);
    }

    public void prepare(Athlete athlete) throws InterruptedException {
      System.out.println(athlete + " ready!");
      synchronized (this) {
        while (!start)
        wait();
        if (start)
          System.out.println(athlete + " go!");
      }
    }

    public synchronized void go() {
      notifyAll();
    }
    
    public void ready() {
      Iterator<Athlete> iter = getPlayers().iterator();
      while (iter.hasNext())
        new Thread(iter.next()).start();
    }

    public void run() {
      start = false;
      System.out.println("Ready......");
      System.out.println("Ready......");
      System.out.println("Ready......");
      ready();
      start = true;
      System.out.println("Go!");
      go();
    }

    public static void main(String[] args) {
      Game game = new Game();
      for (int i = 0; i < 10; i++)
        game.addPlayer(new Athlete(i, game));
      new Thread(game).start();
    }
}


© 著作权归作者所有

共有 人打赏支持
IamOkay
粉丝 190
博文 463
码字总数 376795
作品 0
海淀
程序员
私信 提问
Java Thread及其synchronized,wait,sleep,join,yeid,interrupt

Java SE7 API - Thread: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield%28%29 参考资料:http://blog.csdn.net/lqqmisslll/article/details/54208491 一、线程的简......

YuanyuanL
2015/08/12
0
0
Java多线程总结(未完待续)

1.线程生命周期 (1) 新建 (2) 就绪 (3) 运行 (4) 阻塞:1.正常切换 2.sleep()方法 3.wait()方法 4.执行某个操作进入阻塞状态(等待IO、等待某个通知、试图获得一个同步监视器等)...

Taisuke
2014/06/24
0
0
多线程通信的三大法器,你真的会用吗?

wait, notify, notifyAll 是多线程之间通信最重要的 3 个方法,今天,栈长给大家普及一下它们的知识要点及应用实战。 定义 wait:让持有该对象锁的线程等待; notify: 唤醒任何一个持有该对象...

Java技术栈
11/27
0
0
Core Java基础知识之一(线程私房菜)

Java的高明之处就是在于不断的总结实际应用中不断出现的通用问题,为此提供此类问题的底层实现,向调用者提供解决问题的接口实现,调用者大可不必完全的明白底层的实现原理和实现过程,只要照...

保罗的寓言
2011/05/21
0
0
Java多线程学习总结之---多线程基础

1、线程相关概念   1)、线程与进程的区别     线程是操作系统调度的最小单元,也叫轻量级进程,而进程是操作系统中的应用程序,在进程中可以创建多个线程。   2)、上下文切换   ...

Marksmanbat
08/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

kiss原则

KISS 原则是用户体验的高层境界,简单地理解这句话,就是要把一个产品做得连白痴都会用,因而也被称为“懒人原则”。换句话说来,”简单就是美“。KISS 原则源于 David Mamet(大卫马梅)的电...

NB-One
4分钟前
0
0
Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)

应用场景 前两天我们已经介绍了两种Spring Cloud Stream对消息失败的处理策略: 自动重试:对于一些因环境原因(如:网络抖动等不稳定因素)引发的问题可以起到比较好的作用,提高消息处理的...

程序猿DD
9分钟前
0
0
MYSQL事务处理

INNODB 事务里,所有表引擎必须为INNODB,在非实务表上操作,不会警告,不会报错,但没有效果

关元
48分钟前
3
0
cmake 编译脚本

#!/bin/sh test -d build || mkdir -p build cd build cmake .. make

shzwork
今天
2
0
从零开始实现Vue简单的Toast插件

概述: 在前端项目中,有时会需要通知、提示一些信息给用户,尤其是在后台系统中,操作的正确与否,都需要给与用户一些信息。 1. 实例 在Vue组件的methods内,调用如下代码 `this``.$toast({...

前端小攻略
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部