join、volatile、newSingleThreadLatch 实现线程顺序执行

309 阅读1分钟

1、join

阻塞当前线程、执行调用线程。

public static void main(String[] args) throws InterruptedException {
		Thread thread_1;
		Thread thread_2;
		Thread thread_3;
		
		thread_1=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":1"); 
		});
		
		thread_2=new Thread(()->{
			try {
				thread_1.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+":2"); 
		});
		
		thread_3=new Thread(()->{
			try {
				thread_2.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+":3");
		});
		
		System.out.println("线程启动");
		Thread.sleep(500);
		thread_1.start();
		thread_2.start();
		thread_3.start();
		
	}

2、volatile

性质:

  • 可见性
  • 原子性
  • 禁止指令重排序。

保证线程同步,volatile本身线程不安全,是因为在写入主内存,其他线程可能读取主内存 ,导致读出有误。结合volatile适合的使用场景,可以使用。

  • 对变量的写操作不依赖于当前值。(大白话:修改后的变量值与当前值无关)
  • 该变量没有包含在具有其他变量的不变式中。(大白话:尽量volatile变量不影响其他变量)
static volatile int flag=0;
	
	public static void main(String[] args) throws InterruptedException {
		
		Thread thread_1=new Thread(()->{
			while(true){
				if(flag==1){
					System.out.println(Thread.currentThread().getName()+":1");
					flag++;
					break;
				}
			}
		});
		
		Thread thread_2=new Thread(()->{
			while(true){
				if(flag==2){
					System.out.println(Thread.currentThread().getName()+":2");
					flag++;
					break;
				}
			}
		});
		
		Thread thread_3=new Thread(()->{
			while(true){
				if(flag==3){
					System.out.println(Thread.currentThread().getName()+":3");
					flag++;
					break;
				}
			}
		});
		
		thread_1.start();
		thread_2.start();
		thread_3.start();
		System.out.println("线程启动");
		Thread.sleep(1000);
		flag=1;
		
		
	}

3、newSingleThreadLatch

线程池,按顺序执行,内部有ThreadPoolExecutor实现一个主线程的线程池

  public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
public static void main(String[] args) throws InterruptedException {
		Thread thread_1;
		Thread thread_2;
		Thread thread_3;
		
		thread_1=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":1"); 
		});
		
		thread_2=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":2"); 
		});
		
		thread_3=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":3");
		});
		
		ExecutorService exe=Executors.newSingleThreadExecutor();
		exe.submit(thread_1);
		exe.submit(thread_2);
		exe.submit(thread_3);
		exe.shutdown();
	}

其他

想使用同步线程,CountDownLatch线程实现,但好像只有当countDown()到0才能启动。不对的地方,也希望大家指正。