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

    xiaoxiao2021-03-25  37

     

    1).Android 价值千万   java线程专题:Wait¬ify&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¬ify:2者一起使用

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

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

     

    转载请注明原文地址: https://ju.6miu.com/read-150068.html

    最新回复(0)