java基本教程之线程让步 java多线程教程_java

本章涉及到的内容包括:
1. yield()介绍
2. yield()示例
3. yield() 与 wait()的比较

1. yield()介绍
yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!

2. yield()示例
下面,通过示例查看它的用法。

复制代码 代码如下:

// YieldTest.java的源码
class ThreadA extends Thread{
    public ThreadA(String name){
        super(name);
    }
    public synchronized void run(){
        for(int i=0; i <10; i++){
            System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i);
            // i整除4时,调用yield
            if (i%4 == 0)
                Thread.yield();
        }
    }
}

public class YieldTest{
    public static void main(String[] args){
        ThreadA t1 = new ThreadA("t1");
        ThreadA t2 = new ThreadA("t2");
        t1.start();
        t2.start();
    }
}

(某一次的)运行结果:

复制代码 代码如下:

t1 [5]:0
t2 [5]:0
t1 [5]:1
t1 [5]:2
t1 [5]:3
t1 [5]:4
t1 [5]:5
t1 [5]:6
t1 [5]:7
t1 [5]:8
t1 [5]:9
t2 [5]:1
t2 [5]:2
t2 [5]:3
t2 [5]:4
t2 [5]:5
t2 [5]:6
t2 [5]:7
t2 [5]:8
t2 [5]:9

结果说明:
“线程t1”在能被4整数的时候,并没有切换到“线程t2”。这表明,yield()虽然可以让线程由“运行状态”进入到“就绪状态”;但是,它不一定会让其它线程获取CPU执行权(即,其它线程进入到“运行状态”),即使这个“其它线程”与当前调用yield()的线程具有相同的优先级。

3. yield() 与 wait()的比较
我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而yield()的作用是让步,它也会让当前线程离开“运行状态”。它们的区别是:
(01) wait()是让线程由“运行状态”进入到“等待(阻塞)状态”,而不yield()是让线程由“运行状态”进入到“就绪状态”。
(02) wait()是会线程释放它所持有对象的同步锁,而yield()方法不会释放锁。

下面通过示例演示yield()是不会释放锁的。

复制代码 代码如下:

// YieldLockTest.java 的源码
public class YieldLockTest{

    private static Object obj = new Object();

    public static void main(String[] args){
        ThreadA t1 = new ThreadA("t1");
        ThreadA t2 = new ThreadA("t2");
        t1.start();
        t2.start();
    }

    static class ThreadA extends Thread{
        public ThreadA(String name){
            super(name);
        }
        public void run(){
            // 获取obj对象的同步锁
            synchronized (obj) {
                for(int i=0; i <10; i++){
                    System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i);
                    // i整除4时,调用yield
                    if (i%4 == 0)
                        Thread.yield();
                }
            }
        }
    }
}

(某一次)运行结果:

复制代码 代码如下:

t1 [5]:0
t1 [5]:1
t1 [5]:2
t1 [5]:3
t1 [5]:4
t1 [5]:5
t1 [5]:6
t1 [5]:7
t1 [5]:8
t1 [5]:9
t2 [5]:0
t2 [5]:1
t2 [5]:2
t2 [5]:3
t2 [5]:4
t2 [5]:5
t2 [5]:6
t2 [5]:7
t2 [5]:8
t2 [5]:9

结果说明:
主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.yield();但是,t2是不会获取cpu执行权的。因为,t1并没有释放“obj所持有的同步锁”!

时间: 2024-09-29 00:48:44

java基本教程之线程让步 java多线程教程_java的相关文章

java基本教程之线程休眠 java多线程教程_java

本章涉及到的内容包括:1. sleep()介绍2. sleep()示例3. sleep() 与 wait()的比较 1. sleep()介绍sleep() 定义在Thread.java中.sleep() 的作用是让当前线程休眠,即当前线程会从"运行状态"进入到"休眠(阻塞)状态".sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间:在线程重新被唤醒时,它会由"阻塞状态"变成"就绪状态",从而等待cpu的调度执行

Java中静态方法的线程安全问题

问题描述 Java中静态方法的线程安全问题 Java中多个线程同时访问一个静态方法是否存在线程安全问题? 比如以下代码,两个线程同时对方法中b修改不同的值,会有线程安全问题吗? new Thread(new Runnable() { @Override public void run() { fun(0); } }).start(); new Thread(new Runnable() { @Override public void run() { fun(1); } }).start(); }

Java 并发/多线程教程(五)-相同线程

       本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获.由于个人水平有限,不对之处还望矫正!        相同线程是一并发框架模型,是一个单线程系统向外扩展成多个单线程的系统.这样的结果就是多个单线程并行运行. 为什么是单线程系统?         你也许会感到好奇,为什么当今还有人设计单线程系统.单线程系统之所以这么普及,是因为单线程系统相对于多线程并发系统更为简单.单线程系统不需要与其他线程共享任何数据.这就使得单线程系统可以使用非并发的数据结构,可以更

Java 并发/多线程教程(七)-创建和启动java线程

      本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获.由于个人水平有限,不对之处还望矫正! 创建和启动线程 在java中创建一个线程如下: Thread thread = new Thread(); 调用方法start()来启动一个线程: thread.start();         这个例子没有指定线程执行任何代码,线程将会在启动之后停止.         有两种方式指定线程应该执行什么代码.第一种方式就是创建一个Thread的子类并覆写run()方法.第

Java 并发/多线程教程(十)-线程安全及不可变性

本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获.由于个人水平有限,不对之处还望矫正!        只有在多个线程访问相同的资源时,才会出现竞态条件,并且一个或多个线对相同的资源进操作.如果多个线程读取相同的资源条件,就不会发生这种情况.        我们通过使共享变量不可以变来确保共享变量不被别的线程修改,因此这样的共享变量是线程安全的,下面有个例子: public class ImmutableValue{       private int value =

Java 并发/多线程教程(九)-线程安全和共享资源

         本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获.由于个人水平有限,不对之处还望矫正!       代码被多个线程同时调用是安全的,那么就称之为线程安全.如果一段代码是线程安全的,那么它没有竞态条件.竞态条件只有发生在多个线程更新共享资源.因些,清楚的知道线程执行时什么资源是共享的非常重要. 本地变量        本地变量存储在每个线程自己的栈里,这就意味着本地变量从不与其他线程共享.也就是说本地变量是线程安全的,下面是关于线程安全的本地变量的一个

Java多线程:“基础篇”06之线程让步

1. yield()介绍 yield()的作用是让步.它能让当前线程由"运行状态"进入到"就绪状态",从而让其它具有相同优先级的等待线程获取执行权:但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权:也有可能是当前线程又进入到"运行状态"继续运行! 2. yield()示例 下面,通过示例查看它的用法. // YieldTest.java的源码 class ThreadA extends Thread{

Java 并发/多线程教程(十一)-JAVA内存模型

本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获.由于个人水平有限,不对之处还望矫正!         Java内存模型指定Java虚拟机如何与计算机的内存(RAM)一起工作.Java虚拟机是整个计算机的一个模型,所以这个模型自然包含了一个内存模型--也就是Java内存模型.         如果您想要设计正确的并发程序,那么理解Java内存模型是非常重要的.Java内存模型指定了不同线程如何以及何时可以看到由其他线程写入共享变量的值,以及在必要时如何同步访问共享变量

java中线程同步,线程让步,线程休眠的区别和联系是什么

问题描述 java中线程同步,线程让步,线程休眠的区别和联系是什么 java中线程同步,线程让步,线程休眠的区别和联系是什么 线程的本质还是一个运行中的类, 解决方案 线程同步:是保证多线程安全访问竞争资源的一种手段,java中常用的是加锁机制即synchronized同步代码块实现的. 线程让步的方法是yield(),休眠方法是sleep().sleep()方法和yield()方法都是Thread类的静态方法,都会使当前处于运行状态的线程放弃CPU,把运行机会让给别的线程. 两者的区别在于:s