Java并发编程学习

1.4 wait() 与 notify

例如消息队列生成和消费消息时候,可以用  wait (),  notify 通知对方

wait 和 notify 必须在 synchronized方法里。

1)  wait

释放当前线程的锁,线程进入等待状态,直到其他线程调用该对象的notify

2) notify

其他随机一个线程对应的等待状态解除。可以竞争当前锁。如果要解除所有解除线程的等待状态使用 notifyAll. notify 不会释放锁。

package concurrent;

public class MyQueue {
    private String[] data = new String[10];
    private int size = 0;
    private int getInd = 0;
    private int putInd = 0;

    public synchronized void put(String ele) throws InterruptedException {
        if (size == 10) {
            wait();
            put(ele);
        } else {
            size++;
            data[putInd++] = ele;
            if (putInd == data.length) putInd = 0;
            System.out.println("produce " + ele);
            notify();
        }
    }

    public synchronized void get() throws InterruptedException {
        if (size == 0) {
            wait();
            get();
        } else {
            size--;
            String consume = data[getInd++];
            if (getInd == data.length) getInd = 0;
            System.out.println("consume " + consume);
            notify();
        }
    }
}
package concurrent;

public class ConsumerThread extends Thread{
    private final MyQueue myQueue;

    public ConsumerThread(MyQueue myQueue) {
        this.myQueue = myQueue;
    }

    @Override
    public void run() {
        while (true) {
            try {
                myQueue.get();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
package concurrent;

public class ProducerThread extends Thread {
    private final MyQueue myQueue;
    private int index = 1;

    public ProducerThread(MyQueue myQueue) {
        this.myQueue = myQueue;
    }

    @Override
    public void run() {
        while (true) {
            try {
                if (index == 10) index = 1;
                String putStr = "data" + index;
                myQueue.put(putStr);
                index++;
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

}
package concurrent;

public class Main {
    public static void main(String[] args) {
        MyQueue myQueue = new MyQueue();
        new ConsumerThread(myQueue).start();
        new ProducerThread(myQueue).start();
    }
}

 

1.5 interrupt

1) 什么时候抛出 InterrruptedException

只有函数抛出 InterruptedException,例如,join,wait,sleep,当等待的时候去中断。才会有这个异常。

2)轻量级阻塞与重量级阻塞

能够被中断的阻塞成为轻量级阻塞 (中断干活),不能被中断的阻塞成为重量级阻塞。

3)stop 和interrupt 的区别

stop 会立即停止。线程有可能执行了一般

interrupt 不会停止。设置为中调标志位,配合interrupted 和 isInterruppted 使用

interrupted 标记的是清理标记位是true。(不会中断)

isInterrupted 标记位是 false。

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while (!Thread.currentThread().isInterrupted()) {
                    System.out.println(i++);
                }
                while (true) {
                    System.out.println("Thread next");
                }
            }
        });
        t1.start();
        Thread.sleep(1000);
        t1.interrupt();
    }

 

4)sleep

sleep 不释放锁

 

5) yield 

yield 让出当前cpu。不能保证 立马切换成 就绪状态。当前线程有可能再次被cpu 选中,也有可能不选中

6) join

当一个线程使用join,会让其他线程阻塞住,直到这个线程运行完

1.6 线程的优雅关闭

1) stop 与 destroy

最好不要使用,无法正常释放资源。

2)守护线程

daemon。是主进程伴随的线程,如果主线程退出守护线程退出。 如果没有主线,daemon程则会直接退出。

3)标志位

可以通过标志位 来退出线程

 

1.7 并发编程的核心概念

worker进程和 CPU核数数目相同。

 

1.34 互斥锁

 1) 锁的可如锁,

当一个线程获取锁 进入临界区后,再获取锁可以获得。

2)lock

lock 是一个接口。ReentrantLock 实现了 Lock 接口

 

1.41 线程池原理

1) Executors

 

2) ForkJoinPool

分治加入线程。计算任务。递归分任务

 

posted @ 2024-03-25 18:26  ylxn  阅读(6)  评论(0编辑  收藏  举报