wait/notify
public class Main{
public static Object object = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object){
for (int i = 0; i < 10; i+=2) {
System.out.println(i);
object.notify();
try {
object.wait();
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object){
for (int i = 1; i < 10; i+=2) {
System.out.println(" "+i);
object.notify();
try{
object.wait();
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
}
}
}, "t2");
t1.start();
t2.start();
}
}
ReentrantLock 结合 Condition
public class ReenTranLockTest {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
for (int i = 0; i <10 ; i+=2) {
System.out.println(i);
condition.signal();
try{
condition.await();
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
lock.unlock();
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
for (int i = 1; i <10 ; i+=2) {
System.out.println(" " + i);
condition.signal();
try{
condition.await();
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
lock.unlock();
}
}, "t2");
t1.start();
t2.start();
}
}
Volatile
volatile 修饰内存可见性
public class Volatile implements Runnable {
private static volatile Boolean flag = true;
@Override
public void run() {
while (flag) {
System.out.println(Thread.currentThread().getName() + " - 执行");
}
System.out.println("线程结束");
}
public static void main(String[] args) {
Thread t = new Thread(new Volatile());
t.start();
try {
Thread.sleep(5);
flag = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
join
public class JoinTest {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "start");
try{
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName());
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
}, "Thread1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "start");
try{
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName());
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
}, "Thread2");
t1.start();
t2.start();
try{
t1.join();
t2.join();
}catch (InterruptedException ex){
ex.printStackTrace();
}
System.out.println("over");
}
}
CountDownLatch 闭锁
public class CountDownLatchTest {
public static void main(String[] args) {
try {
countDownLatch();
}catch (Exception ex){
ex.printStackTrace();
}
}
private static void countDownLatch() throws Exception{
int thread = 3 ;
long start = System.currentTimeMillis();
final CountDownLatch countDown = new CountDownLatch(thread);
for (int i= 0 ;i<thread ; i++){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread run");
try {
Thread.sleep(2000);
countDown.countDown();
System.out.println("thread end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
countDown.await();
long stop = System.currentTimeMillis();
System.out.printf("main over total time=%d",stop-start);
}
}
主线程会在所有线程都调用countDown
方法后,才会用执行countDown.await();
后面的语句
CyclicBarrier 栅栏
private static void cyclicBarrier() throws Exception {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3) ;
new Thread(new Runnable() {
@Override
public void run() {
LOGGER.info("thread run");
try {
cyclicBarrier.await() ;
} catch (Exception e) {
e.printStackTrace();
}
LOGGER.info("thread end do something");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
LOGGER.info("thread run");
try {
cyclicBarrier.await() ;
} catch (Exception e) {
e.printStackTrace();
}
LOGGER.info("thread end do something");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
LOGGER.info("thread run");
try {
Thread.sleep(5000);
cyclicBarrier.await() ;
} catch (Exception e) {
e.printStackTrace();
}
LOGGER.info("thread end do something");
}
}).start();
LOGGER.info("main thread");
}
CyclicBarrier 中文名叫做屏障或者是栅栏,也可以用于线程间通信。
和CountDownLatch的区别是,
CyclicBarrier 用于参与者线程之间的互相等待,当所有参与者线程都执行到cyclicBarrier.await()
的时候,再继续往下执行
而CountDownLatch是其他未参与线程,等待参与者都执行countDown
方法后,再继续往下执行。
线程响应中断
public class StopThread implements Runnable {
@Override
public void run() {
while ( !Thread.currentThread().isInterrupted()) {
// 线程执行具体逻辑
System.out.println(Thread.currentThread().getName() + "运行中。。");
}
System.out.println(Thread.currentThread().getName() + "退出。。");
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new StopThread(), "thread A");
thread.start();
System.out.println("main 线程正在运行") ;
TimeUnit.MILLISECONDS.sleep(10) ;
thread.interrupt();
}
}
可以采用中断线程的方式来通信,调用了 thread.interrupt() 方法其实就是将 thread 中的一个标志属性置为了 true。
并不是说调用了该方法就可以中断线程,如果不对这个标志进行响应其实是没有什么作用(这里对这个标志进行了判断)。
也可以用公共变量标志位,来实现。