Run

每个Thread中需要实现的方法, 如果直接调用的话, 会是和单线程一样的效果, 要另起线程需要使用start().

start

新起线程调用run(). 主线程不等待直接往下执行

Yield

Yield会告诉jvm, 它愿意让出当前的处理器使用, 让其他线程被执行. 这意味着它并非在执行非常紧急的任务, 这只是一个hit, 可能会被忽略, 可能并不会发生任何作用. 需要有详细的profiling和benchmarking来保证这个调用达到预期的效果.

  • Yield是一个静态和原生的方法
  • Yield告诉当前线程, 给予线程池中同等优先级的其他线程被执行的机会.
  • Yield并不保证会立即将当前正在执行的线程状态转变为runnable.
  • Yield只会将一个线程的状态从Running变成Runnable, 而不是wait或blocked状态.

Join

  • 线程实例的join调用, 可以让这个线程执行的开始被关联到另一个线程执行的结束上, 这样直到另一个线程结束后这个线程才会开始执行. 如果对一个线程调用了join, 那么当前running的线程会被block, 直到那个线程执行结束.
  • 如果在join中设置了timeout, 那么在timeout后会取消join, 当timeout时, 主线程会变成和任务线程一样的执行候选, 但是这个时间准确度取决于操作系统, 并不能保证是精确的.
  • join和sleep一样, 会相应interrupt并抛出一个InterruptedException

如果有一个Thread a, 在a.start()后面(可以使用thread.isAlive()判断). 使用a.join() 可以使主线程等待a执行完. 如果同时有多个线程a, b, c, 而d需要等abc执行完后才能执行, 可以在d start之前使用a.join, b.join, c.join, 也可以把a, b, c的start放到d的run方法里面, 使用a.join, b.join, c.join, 可以用参数设置timeout时间.

class JoiningThread extends Thread {
// NOTE: UNTESTED!
private String name;
private Thread nextThread; public JoiningThread(String name) {
this(name, null);
} public JoiningThread(String name, Thread other) {
this.name = name;
this.nextThread = other;
} public String getName() {
return name;
} @Override
public void run() {
System.out.println("Hello I'm thread ".concat(getName()));
if (nextThread != null) {
while(nextThread.isAlive()) {
try {
nextThread.join();
} catch (InterruptedException e) {
// ignore this
}
}
}
System.out.println("I'm finished ".concat(getName()));
}
}

使用的时候

public static void main(String[] args) {
Thread d = WaitingThread("d");
Thread c = WaitingThread("c", d);
Thread b = WaitingThread("b", c);
Thread a = WaitingThread("a", b); a.start();
b.start();
c.start();
d.start(); try {
a.join();
} catch (InterruptedException e) {}
}

sleep(): 需要时间作为参数, 可以被interrupt.

wait(): wait会释放当前持有的锁, 并进入sleep状态. 和join()的区别是, wait需要额外的notify来终止.

notify(): synchronized锁定的是什么资源, 就在什么资源上调用notify. notify会唤醒在当前锁定对象上使用了wait()的一个线程. 要注意的是, 调用notify时并未释放锁定的对象资源, 它只是告诉等待的线程, 你可以醒过来了. 而锁的释放要等到synchronized代码块执行的结束. 所以如果对一个资源调用了notify(), 而调用者本身还需要10秒中才能完成synchronized的代码块, 被唤醒的线程还需要再等10秒才能继续执行.

notifyAll(): 会唤醒当前锁定对象上等待的所有线程, 最高优先级的线程会拿到对象锁并继续执行(这不是完全保证的). 其他和notify是一样的.

上面的类可以改写为

class WaitingThread extends Thread {
// NOTE: UNTESTED! private Thread previousThread;
private String name; public WaitingThread(String name) {
this(name, null);
} public WaitingThread(String name, Thread other) {
this.name = name;
this.previousThread = other;
} public String getName() {
return name;
} @Override
public void run() {
System.out.println("Hello I'm thread ".concat(getName()));
// Do other things if required // Wait to be woken up
while(true) {
synchronized(this) {
try {
wait();
break;
} catch (InterruptedException e) {
// ignore this
}
}
} System.out.println("I'm finished ".concat(getName())); // Wake up the previous thread
if (previousThread != null) {
synchronized(previousThread) {
previousThread.notify();
}
}
}
}

对于 synchronized, wait 和 notifyAll 的测试. 其中Producer模拟一个队列生产者, Consumer1和Consumer2模拟队列消费者, 队列是同步对象, 得到锁的线程, 会通过wait()或notifyAll()通知其他线程继续尝试得到锁.

Producer.java 

class Producer implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY; public Producer(List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
} @Override
public void run() {
int counter = 0;
while (true) {
try {
produce(counter++);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
} private void produce(int i) throws InterruptedException {
System.out.println(Thread.currentThread().getName() + ": produce()");
synchronized (taskQueue) {
System.out.println(Thread.currentThread().getName() + ": produce().synchronized >>");
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println(Thread.currentThread().getName() + ": produce().synchronized ||");
taskQueue.wait();
} Thread.sleep(500 + (long)(Math.random() * 500));
taskQueue.add(i);
System.out.println(Thread.currentThread().getName() + ": Produced: " + i);
taskQueue.notifyAll();
System.out.println(Thread.currentThread().getName() + ": produce().synchronized <<");
}
}
}

Consumer.java

class Consumer implements Runnable {
private final List<Integer> taskQueue; public Consumer(List<Integer> sharedQueue) {
this.taskQueue = sharedQueue;
} @Override
public void run() {
while (true) {
try {
consume();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
} private void consume() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + ": consume()");
synchronized (taskQueue) {
System.out.println(Thread.currentThread().getName() + ": consume().synchronized >>");
while (taskQueue.isEmpty()) {
System.out.println(Thread.currentThread().getName() + ": consume().synchronized ||");
taskQueue.wait();
}
Thread.sleep(500 + (long)(Math.random() * 500));
int i = (Integer) taskQueue.remove(0);
System.out.println(Thread.currentThread().getName() + ": Consumed: " + i);
taskQueue.notifyAll();
System.out.println(Thread.currentThread().getName() + ": consume().synchronized <<");
}
}
}

ProducerConsumerExample.java

public class ProducerConsumerExample {
public static void main(String[] args) {
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 5;
Thread tProducer = new Thread(new Producer(taskQueue, MAX_CAPACITY), "Producer");
Thread tConsumer = new Thread(new Consumer(taskQueue), "Consumer1");
Thread tConsumer2 = new Thread(new Consumer(taskQueue), "Consumer2");
tProducer.start();
tConsumer.start();
tConsumer2.start();
}
}

Java中run(), start(), join(), wait(), yield(), sleep()的使用的更多相关文章

  1. Java多线程中run(), start(), join(), wait(), yield(), sleep()的使用

    Run 每个Thread中需要实现的方法, 如果直接调用的话, 会是和单线程一样的效果, 要另起线程需要使用start(). start 新起线程调用run(). 主线程不等待直接往下执行 Yield ...

  2. java中sleep和join和yield和wait和notify的区别

    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...

  3. java 中的fork join框架

    文章目录 ForkJoinPool ForkJoinWorkerThread ForkJoinTask 在ForkJoinPool中提交Task java 中的fork join框架 fork joi ...

  4. java中interrupt、join、sleep、notify、notifyAll、wait详解

    首先介绍一下中断概念:举个例子容易理解一点 例子:假如你正在给朋友写信,电话铃响了.这时,你放下手中的笔,去接电话.通话完毕,再继续写信.这个例子就表现了中断及其处理过程:电话铃声使你暂时中止当前的工 ...

  5. 关于多线程中sleep、join、yield的区别

    好了.说了多线程,那就不得不说说多线程的sleep().join()和yield()三个方法的区别啦 1.sleep()方法 /** * Causes the currently executing ...

  6. JAVA中的Fork/Join框架

    看了下Java Tutorials中的fork/join章节,整理下. 什么是fork/join框架 fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核 ...

  7. java中start()、yield、setDeamon()

    本节主要说明以下三个问题 start()的启动顺序不代表线程的启动顺序 yeild的作用 守护线程 1.start()与线程启动顺序 package foreverly.cn.chapter1; pu ...

  8. Java进程与多线程+线程中的join、yield、wait等方法+synchronized同步锁使用

    首先了解什么是多线程与进程 进程:是一个执行过程,动态的概念 --->会分配内存线程:是进程的一个单元,线程是系统最小的执行单元 详解: http://blog.csdn.net/luoweif ...

  9. 可惜Java中没有yield return

    项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...

随机推荐

  1. iOS开发200个tips总结(一)

    tip 1 :  给UIImage添加毛玻璃效果 func blurImage(value:NSNumber) -> UIImage { let context = CIContext(opti ...

  2. Xcode7.3更新后插件失效的解决方法

    昨天发布的Xcode7.3,用了一天的时间终于装上了(网络不给力),突然发现原来所使用的插件不能用了,当时表情如下: 记得在更新7.2的时候也是这样的,当时重新下载的插件安装成功,但是未免有些麻烦,经 ...

  3. 【Android】保存Fragment切换状态

    前言 一般频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿体验就非常不好了,这里分享一个方法. 声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.c ...

  4. Swift开发第十篇——可变参数函数&初始化方法顺序

    本篇分为两部分: 一.Swift中的可变参数函数 二.初始化方法的顺序 一.Swift中的可变参数函数 可变参数函数指的是可以接受任意多个参数的函数,在 OC 中,拼接字符串的函数就属于可变参数函数 ...

  5. 我的android学习经历7

    android签名后报错的问题 Duplicate id @+id/imageView, already defined earlier in this layout,android生成报错 这个是项 ...

  6. yii2超好用的日期组件和时间组件

    作者:白狼 出处:http://www.manks.top/yii2_datetimepicker.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接 ...

  7. List 简单升\降序实现

    public class User { public int Id { get; set; } public string Code { get; set; } } //示例 //升序 list.So ...

  8. SQL Server(九)——事务

    事务: 保障流程的完整执行,就像银行取钱,先在你账上扣钱,然后存入别人的账上:但是从你账上扣完钱了,突然网断了,对方没有收到钱,那么此时你的钱也没了,别人的钱也没加上,事务为了防止此类情况的出现. 事 ...

  9. SQL Server 2012实施与管理实战指南(笔记)——Ch3Alwayson可用组

    3.AlwaysOn可用组 Alwayson支持的,是一个可用性组,每个可用性组是包含了多个用户数据库的容器,可用性组内的数据库可以作为一个整体进行故障转移. AlwaysOn关键特性: 一.类似集群 ...

  10. 自动kill慢查询

    在生产环境中,DB服务器经常会被并发的慢查询压挂,因此事前进行sql审核避免烂SQL很重要.万一不小心慢sql还是跑到线上,并且并发还不小,这是dba肯定会收到告警.dba上线处理第一时间是定位并ki ...