目录
1.Thread join
2.Thread sleep
3. wait/notify
4. interrupt/interrupted/isInterruped
1.Thread join
t1.join作用就是等t1运行完,主线程才会继续往下执行
public class MyThread1 extends Thread {
@Override
public void run() {
try {
TimeUnit.MICROSECONDS.sleep(1000);
System.out.println("1");
} catch (InterruptedException e) {
}
}
}
public class MyThread2 extends Thread {
@Override
public void run() {
try {
TimeUnit.MICROSECONDS.sleep(1);
System.out.println("2");
} catch (InterruptedException e) {
}
}
}
public class ThreadTest {//运行结果可能是1,2,也可能是2,1
public static void main(String[] args) throws InterruptedException {
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t1.start();
t2.start();
}
}
public class ThreadTest {//运行结果只有一种1,2
public static void main(String[] args) throws InterruptedException {
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t1.start();
t1.join();
t2.start();
}
}
join源码分析:
2.Thread sleep
Thread.sleep(1000);//线程sleep1秒后,不一定就会获取cpu执行权,sleep(1000)只是代表未来1秒内,此线程不参与cpu的竞争,1秒后再参与,1秒后线程被唤醒进入就绪状态,可以参与cpu的分配了,但是最后cpu分配给哪个线程并不能确定。
Thread.sleep(0):作用:触发cpu重新进行一次分配
3. wait/notify
wait/notify都是Object的方法,但是调用wait的线程会被阻塞(obj1.wait,obj2.wait,obj3.wait最终阻塞的都是当前调用他们的线程,obj1.notify会唤醒等待obj1的线程,并不会唤醒通过obj2.wait从而阻塞的线程,obj就是多线程的共享资源,现在明白为什么不是thread.wait,thread.notify了,因为这样的话是在同一个线程内部的操作,对于多线程没有任何意义),调用bags.wait的线程会释放锁,bags.notify()唤醒等待bags的一个线程,bags.notigyAll唤醒等待bags的所有线程
//生产者:
public class Producer implements Runnable {
private Queue<String> bags;
public Producer(Queue<String> bags) {
this.bags = bags;
}
@Override
public void run() {
while (true) {
synchronized (bags) {
if (bags.size() > 0) {
try {
bags.wait();
} catch (InterruptedException e) {
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产者-生产bag");
bags.add("bag");
bags.notifyAll();//唤醒等待bags的所有线程
}
}
}
}
//消费者:
public class Consumer implements Runnable {
private Queue<String> bags;
public Consumer(Queue<String> bags) {
this.bags = bags;
}
@Override
public void run() {
while (true) {
synchronized (bags) {
if (bags.size() == 0) {
try {
bags.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者-消费" + bags.remove());
bags.notifyAll();//唤醒等待bags的所有线程
}
}
}
}
//测试:
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Queue<String> bags = new LinkedList<>();
Producer producer = new Producer(bags);
Consumer consumer = new Consumer(bags);
Thread t1 = new Thread(producer);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();
}
}
运行结果:
4. interrupt/isInterruped/interrupted
thread1.isInterrupted默认为false,调用thread1.interrupt后thread1.isInterrupted变为true
public class MyThread1 extends Thread {
@Override
public void run() {
int i = 0;
while (true) {
i++;
}
}
}
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyThread1());
thread.start();
thread.interrupt();//但际上只是给线程设置一个中断标志,线程仍会继续运行。
}
}
//那怎么能真正实现中断
public class MyThread1 extends Thread {
@Override
public void run() {
int i = 0;
while (!Thread.currentThread().isInterrupted()) {//判断中断标志位是否可中断了
i++;
}
}
}
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyThread1());
thread.start();
thread.interrupt();//但际上只是给线程设置一个可中断标志,线程仍会继续运行。
}
}
//没有while的线程如何中断
public class MyThread1 extends Thread {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyThread1());
thread.start();
thread.interrupt();//此时正在sleep/wait/join的线程会被唤醒并且抛出中断异常
}
}
/**
什么时候thread.interrupt()中断才有意义,当run线程没有被sleep/wait/join
并且没有Thread.currentThread().isInterrupted()的判断,
调用hread.interrupt()只是改变了可中断,但是并没有任何意义的。正常执行结束的run,无需中断
**/
Thread.interruped:不仅返回当前线程是否被中断,还会使得所有线程的中断标志位复位为false
public class MyThread1 extends Thread {
@Override
public void run() {
int i = 0;
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().isInterrupted());
Thread.interrupted();
System.out.println(Thread.currentThread().isInterrupted());
}
}
}
}
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyThread1());
thread.start();
System.out.println(thread.isInterrupted());
thread.interrupt();//但际上只是给线程设置一个中断标志,线程仍会继续运行。
}
}