JAVA多线程顺序执行(使用join,lock,condition,信号量)原理和java源代码

java多线程顺序执行问题

使用join

假设我要让3个线程按照顺序打印ABC,那么可以使用Join,如果要求多线程按顺序循环打印,则不能用join了

join关键字

join是Thread类的一个方法,启动线程后直接调用。在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。
join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。

具体代码
package googleTest;

public class ThreadTest {  
    public static void main(String[] args) throws InterruptedException {  
        Thread t1 = new Thread(new Runner("A"));  
        Thread t2 = new Thread(new Runner("B"));  
        Thread t3 = new Thread(new Runner("C"));  
        t1.start();  
        t1.join();  
        t2.start();  
        t2.join();  
        t3.start();  
        t3.join();  
      
    }  
      
}  
  
class Runner implements Runnable{ 
	public String name;
	
	Runner(String name)
	{
		this.name=name;
	}
  
    @Override  
    public void run() {  
        System.out.println(name+"");  
          
    }  
      
} 

使用lock和全局变量

lock时注意unlock就可以啦

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
public class ThreadTest3 {
	private static Lock lock=new ReentrantLock();
     private static int state = 0;
    
    static class ThreadA extends Thread {
         @Override
         public void run() {
            	lock.lock();
                 if (state % 3 == 0) {
                     System.out.println("A");
                     state++;
                 }
                 lock.unlock();
         }
     }
     
     static class ThreadB extends Thread {
         @Override
         public void run() {
                 lock.lock();
                if (state % 3 == 1) {
                     System.out.println("B");
                    state++;
                 }
                 lock.unlock();
             }
            
         }
     
     static class ThreadC extends Thread {
         @Override
         public void run() {
                 lock.lock();
                 if (state % 3 == 2) {
                     System.out.println("C");
                     state++;
                }
                 lock.unlock();
         }
     }
     
     public static void main(String[] args) {
	     new ThreadA().start();
         new ThreadB().start();
         new ThreadC().start();
     }
     
 }

使用condition

condition关键字

就拿生产者消费者模式来说,当仓库满了的时候,又再执行到 生产者 线程的时候,会把 该 生产者 线程进行阻塞,再唤起一个线程.

但是此时唤醒的是消费者线程还是生产者线程,是未知的。如果再次唤醒的还是生产者线程,那么还需要把它进行阻塞,再唤起一个线程,再此循环,直到唤起的是消费者线程。这样就可能存在 时间或者资源上的浪费,

所以说 有了Condition 这个东西。Condition 用 await() 代替了 Object 的 wait() 方法,用 signal() 方法代替 notify() 方法。注意:Condition 是被绑定到 Lock 中,要创建一个 Lock 的 Condition 必须用 newCondition() 方法。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest2 {
     private static Lock lock = new ReentrantLock();
     private static int count = 0;
     private static Condition A = lock.newCondition();
     private static Condition B = lock.newCondition();
     private static Condition C = lock.newCondition();
    
     static class ThreadA extends Thread {
 
         @Override
         public void run() {
             lock.lock();
             try {
                 for (int i = 0; i < 10; i++) {
                     while (count % 3 != 0)
                         A.await(); // 会释放lock锁
                        System.out.print("A");
                     count++;
                     B.signal(); // 唤醒相应线程
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
            } finally {
                 lock.unlock();
             }
         }
         
     }
     
     static class ThreadB extends Thread {
 
         @Override
        public void run() {
             lock.lock();
             try {
                for (int i = 0; i < 10; i++) {
                    while (count % 3 != 1)
                         B.await();
                     System.out.print("B");
                     count++;
                   C.signal();
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
            } finally {
                 lock.unlock();
             }
        }
         
     }

     static class ThreadC extends Thread {

         @Override
         public void run() {
             lock.lock();
             try {
                 for (int i = 0; i < 10; i++) {
                     while (count % 3 != 2)
                         C.await();
                     System.out.println("C");
                     count++;
                     A.signal();
              }
             } catch (InterruptedException e) {
	            e.printStackTrace();
             } finally {
                 lock.unlock();
             }
         }
       
    }
     
     public static void main(String[] args) throws InterruptedException {
         new ThreadA().start();
         new ThreadB().start();
         ThreadC threadC = new ThreadC();
         threadC.start();
         threadC.join();
         System.out.println(count);
     }
 }

使用信号量

Semaphore关键字

Semaphore为并发包中提供用于控制某资源同时可以被几个线程访问的类。一般用于限制线程访问的资源个数。也可用于线程间的信号传递。
 import java.util.concurrent.Semaphore;
  
 public class ThreadTest4 {
      private static Semaphore A = new Semaphore(1);
      private static Semaphore B = new Semaphore(1);
      private static Semaphore C = new Semaphore(1);
      
     static class ThreadA extends Thread {
  
         @Override
         public void run() {
             try {
                 for (int i = 0; i < 10; i++) {
                     A.acquire();
                     System.out.print("A");
                     B.release();
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         
     }
     
     static class ThreadB extends Thread {
 
         @Override
         public void run() {
             try {
                 for (int i = 0; i < 10; i++) {
                     B.acquire();
                     System.out.print("B");
                     C.release();
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         
     }
     
     static class ThreadC extends Thread {
 
        @Override
         public void run() {
             try {
                 for (int i = 0; i < 10; i++) {
                     C.acquire();
                     System.out.println("C");
                     A.release();
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         
     }
     
     public static void main(String[] args) throws InterruptedException {
         B.acquire(); C.acquire(); // 开始只有A可以获取, BC都不可以获取, 保证了A最先执行
         new ThreadA().start();
         new ThreadB().start();
         new ThreadC().start();
     }
 }




你可能感兴趣的:(JAVA多线程顺序执行(使用join,lock,condition,信号量)原理和java源代码)