Java多线程yield,wait,notify,notifyall,join守护线程的区别
博客专区 > IamOkay 的博客 > 博客详情
Java多线程yield,wait,notify,notifyall,join守护线程的区别
IamOkay 发表于3年前
Java多线程yield,wait,notify,notifyall,join守护线程的区别
  • 发表于 3年前
  • 阅读 23
  • 收藏 2
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

摘要: 在java多线程中,为了更好的实现线程间的通信和同步问题,java 设计了一些可以使用的方法,理解这些几种,将更好的掌握线程同步问题

参考: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();
    }
}


共有 人打赏支持
粉丝 169
博文 429
码字总数 330179
×
IamOkay
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: