Android 价值千万的java线程专题:Wait&notify&join&Yield

 

1).Android 价值千万   java线程专题:Wait&notify&join&Yield

http://blog.csdn.net/whb20081815/article/details/65627387

2).Android 价值千万    java多线程同步 <二>Callable和Future&FutureTask

http://blog.csdn.net/whb20081815/article/details/65630694

3).Android 价值千万    java多线程<三>生产者消费者模型四种实现方法

http://blog.csdn.net/whb20081815/article/details/65635647

 4).Android 价值千万    java多线程同步 <四> synchronized&Lock&Atomic6种方式

http://blog.csdn.net/whb20081815/article/details/66971983

 

5).Android 价值千万java多线程同步 <五>CountDownLatch(计数器)和Semaphore(信号量)

http://blog.csdn.net/whb20081815/article/details/68498371

6).Android AsyncTask 那些你不知道的事

https://blog.csdn.net/WHB20081815/article/details/70332209

7).Android 厉害了ThreadLocal的工作原理和实例分析

https://blog.csdn.net/WHB20081815/article/details/66974651

8).Android Handle消息机制:秒懂Looper、Handler、Message三者关系

https://blog.csdn.net/WHB20081815/article/details/67639060

9).Android 性能优化<八> 多线程优化和线程管理

https://blog.csdn.net/WHB20081815/article/details/77775444

 

 

  创建线程的2种方式

1.实现Runnable接口的多线程例子

2.测试扩展Thread类实现的多线程程序

 

Thread有setName("MyThread");Runnable没有

 

class Thread implements Runnable

 

RunTest runTest=new RunTest();
runTest.run();//run

 

class RunTest implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            for (long k = 0; k < 100000000; k++) ;
            Log.d("","i"+i);
        }
    }
}
方式二:
MyThread myThread=new MyThread();
myThread.start();//start
class MyThread extends Thread{//继承

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            for (long k = 0; k < 100000000; k++) ;
            Log.d("","i"+i+Thread.currentThread().getName());

        }
    }
}

 

Thread t2 = new Thread(new RunTest());
t2.start();

 

 

得到线程:Thread.currentThread()

1.最简单的用法:睡眠  Thread.sleep(long millis),放在当前线程

睡眠的位置:为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内

 

 

2、线程的优先级和线程让步yield()

 

线程的让步是通过Thread.yield()来实现的。yield()方法的作用是:暂停当前正在执行的线程对象,并执行其他线程。

因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行

 

 

设置线程的优先级:线程默认的优先级是创建它的执行线程的优先级。可以通过setPriority(int newPriority)更改线程的优先级。例如:

 

        Thread t = new MyThread();

        t.setPriority(8);

        t.start();

 

线程优先级为1~10之间的正整数

列子:

 

public void testYield(){
    RunTest runTest=new RunTest();
    runTest.run();//run

    MyThread myThread=new MyThread();
    myThread.start();//start

    Thread t2 = new Thread(new RunTest());
    t2.start();
}

 

 

class RunTest implements Runnable{//实现

    @Override
    public void run() {


        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 10; i++) {
            Log.d("MainActivity","RunTest 线程"+Thread.currentThread().getName() + ""+i + "次执行!");
        }
    }
}

 

class MyThread extends Thread{//继承

        @Override
        public void run() {
//            Log.d("","currentThread()"+Thread.currentThread().getName());
            setName("MyThread");
            for (int i = 0; i < 10; i++) {
                Log.d("MainActivity","MyThread 线程"+Thread.currentThread().getName() + "="+i + "次执行!");
                Thread.yield();//即使其他线程sleep,还是会先暂停本线程任务
            }
        }
    }

 

 

 

注意:并不是等待该线程完全执行才执行让步的线程,所以这个是不同步的

线程2第2次执行!

线程2第3次执行!

线程1第0次执行!

线程1第1次执行!

线程1第2次执行!

线程1第3次执行!

线程1第4次执行!

线程1第5次执行!

线程1第6次执行!

线程1第7次执行!

线程1第8次执行!

线程1第9次执行!

线程2第4次执行!

线程2第5次执行!

线程2第6次执行!

 

3.join()方法

 

Thread的非静态方法join()让一个线程B“加入”到另外一个线程A的尾部。B.join(),B优先执行(参加)。例如:

 

        Thread A = new MyThread();

        t.start();

        B.join();

 

public void testWait(){

    WaitThread waitThread = new WaitThread();
    // 启动计算线程
    waitThread.start();

    // 线程Main拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者
    /**
     * 测试wait和Notify
     */
    synchronized (waitThread) {
        try {
            Log.d("MainActivity","等待对象waitThread完成计算。。。");

            // 当前线程A等待
            waitThread.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Log.d("MainActivity","waitThread对象计算的总和是:" + waitThread.total);

    }

}

 

 

public class WaitThread extends Thread {

    int total;

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 101; i++) {
                total += i;
            }
            // (完成计算了)唤醒在此对象监视器上等待的单个线程,在本例中线程A被唤醒
            notify();
        }
    }

}

 

 

 

 

4.notify()和wait()是配套使用的

 

 

 void notify() 
          唤醒在此对象监视器上等待的单个线程。
 void notifyAll() 
          唤醒在此对象监视器上等待的所有线程。
 void wait() 
          导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll()方法。

 

 

关于等待/通知,要记住的关键点是:

必须从同步环境内调用wait()、notify()、notifyAll()方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。

 

public void testWait(){

    WaitThread waitThread = new WaitThread();
    // 启动计算线程
    waitThread.start();

    // 线程Main拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者
    /**
     * 测试wait和Notify
     */
    synchronized (waitThread) {
        try {
            Log.d("MainActivity","等待对象waitThread完成计算。。。");

            // 当前线程A等待
            waitThread.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.d("MainActivity","waitThread对象计算的总和是:" + waitThread.total);
    }
}
public class WaitThread extends Thread {

    int total;

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 101; i++) {
                total += i;
            }
            // (完成计算了)唤醒在此对象监视器上等待的单个线程,在本例中线程A被唤醒
            notify();
        }
    }
}

 

 

总结:4个方法都是不同步的,线程会交叉

Wait&notify:2者一起使用

&join&Yield:2者的作用相反,一个是加入(join),一个是让步(yield)

AS代码地址:不知道为什么传不上!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值