T1、T2、T3三个线程顺序(环形)执行
方法一:标志以及加锁操作
package org.example1;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Company Zhengzhou University (zzu)
* @Author ZhiChao He
* @Date 2021/4/23 10:48
* @Version 1.0
*/
public class ShareThread {
private int flag = 1;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void Test01() throws InterruptedException {
lock.lock();
try {
while (flag != 1) {
c1.await();
}
System.out.println("正在执行的是:" + Thread.currentThread().getName() + ";之后执行T2");
flag = 2;
c2.signal();// 通知一个线程来执行
} finally {
lock.unlock();
}
}
public void Test02() throws InterruptedException {
lock.lock();
try {
while (flag != 2) {
c2.await();
}
System.out.println("正在执行的是:" + Thread.currentThread().getName() + ";之后执行T3");
flag = 3;
c3.signal();// 通知一个线程来执行
} finally {
lock.unlock();
}
}
public void Test03() throws InterruptedException {
lock.lock();
try {
while (flag != 3) {
c3.await();
}
System.out.println("正在执行的是:" + Thread.currentThread().getName() + ";之后执行T1");
flag = 1;
c1.signal();// 通知一个线程来执行
} finally {
lock.unlock();
}
}
public static class ThreadDemo {
public static void main(String[] args) {
ShareThread sh = new ShareThread(); //我使用的是JDK1.8,如果是1.8之前的版本,需要在类对象前面加final
new Thread(new Runnable() {
@Override
public void run() {
try {
sh.Test01();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T1").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
sh.Test02();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T2").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
sh.Test03();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T3").start();
}
}
}
正在执行的是:T1;之后执行T2
正在执行的是:T2;之后执行T3
正在执行的是:T3;之后执行T1
方法二:在main线程中利用join方法
package org.example1;
/**
* @Company Zhengzhou University (zzu)
* @Author ZhiChao He
* @Date 2021/4/23 11:04
* @Version 1.0
*/
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ThreadJoinTest1 t1 = new ThreadJoinTest1("今天");
ThreadJoinTest1 t2 = new ThreadJoinTest1("明天");
ThreadJoinTest1 t3 = new ThreadJoinTest1("后天");
/*
* 通过join方法来确保t1、t2、t3的执行顺序
* */
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
/*错误的写法
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();*/
}
}
class ThreadJoinTest1 extends Thread{
public ThreadJoinTest1(String name){
super(name);
}
@Override
public void run(){
for(int i=0;i<5;i++){
System.out.println(this.getName() + ":" + i);
}
}
}
join方法的作用?
join方法是通过调用线程的wait方法来达到同步的目的的。例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的。
join方法传参和不传参的区别?
join方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。
/*
* 本测试程序主要是测试join方法的传参与不传参的区别
* */
package com.threadDemo;
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ThreadJoinTest t1 = new ThreadJoinTest("夏天");
ThreadJoinTest t2 = new ThreadJoinTest("秋天");
t1.start();
/**join方法可以传递参数,join(10)表示main线程会等待t1线程10毫秒,10毫秒过去后,
* main线程和t1线程之间执行顺序由串行执行变为普通的并行执行
*/
t1.join(10);
t2.start();
}
}
class ThreadJoinTest extends Thread{
public ThreadJoinTest(String name){
super(name);
}
@Override
public void run(){
for(int i=0;i<1000;i++){
System.out.println(this.getName() + ":" + i);
}
}
}