Java并发编程知识:
1. synchronized
package demo02;
/**
* @author Jeady
* @Date 2020/3/9
*/
public class MyRunnablesyn implements Runnable {
static int tickets = 100;
Object object = new Object();
@Override
public void run() {
while (true){
sell();
}
}
private synchronized void sell() {
if (tickets>0){
System.out.println(Thread.currentThread().getName()+"正在出售:"+tickets+"张电影票");
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
--tickets;
}
}
public static void main(String[] args) {
MyRunnablesyn myRunnablesyn = new MyRunnablesyn();
Thread thread1 = new Thread(myRunnablesyn);
thread1.setName("窗口一:");
Thread thread2 = new Thread(myRunnablesyn);
thread2.setName("窗口二:");
Thread thread3 = new Thread(myRunnablesyn);
thread3.setName("窗口三:");
thread1.start();
thread2.start();
thread3.start();
}
}
结果正常跑完:
2. ReentrantLock
package demo02;
import demo.Main;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Jeady
* @Date 2020/3/9
*/
public class MyRunnableImpl implements Runnable {
private int ticket = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true){
lock.lock();
if (ticket>0){
System.out.println(Thread.currentThread().getName()+"正在卖票"+ticket+"张电影票");
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
--ticket;
}
lock.unlock();
}
}
public static void main(String[] args) {
MyRunnableImpl myRunnable = new MyRunnableImpl();
Thread thread1 = new Thread(myRunnable);
thread1.setName("窗口一:");
Thread thread2 = new Thread(myRunnable);
thread2.setName("窗口二:");
Thread thread3 = new Thread(myRunnable);
thread3.setName("窗口三:");
thread1.start();
thread2.start();
thread3.start();
}
}
结果:
3.CountDownLatch
package demo02;
import java.util.concurrent.CountDownLatch;
/**
* @author Jeady
* @Date 2020/3/9
*/
public class MyCountDownLatch implements Runnable {
private CountDownLatch begin;
private CountDownLatch end;
public MyCountDownLatch(CountDownLatch begin, CountDownLatch end) {
this.begin=begin;
this.end=end;
}
@Override
public void run() {
try {
begin.await();
System.out.println(Thread.currentThread().getName());
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(2);
for (int i=0;i<2;i++){
Thread thread = new Thread(new MyCountDownLatch(begin,end));
thread.start();
}
try {
System.out.println("thread begin");
begin.countDown();
end.await();
System.out.println("thread end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果:
4. CyclicBarrier
循环屏障, 它允许一组线程互相等待,直到达到某个公共屏障点. 在等待线程后可以重用
package demo02;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author Jeady
* @Date 2020/3/9
*/
public class MyCyclicBarrier {
//等待5个线程都启动了,一起执行
private static java.util.concurrent.CyclicBarrier cyclicBarrier = new java.util.concurrent.CyclicBarrier(5);
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0;i<=20;i++){
final int index = i;
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
executorService.execute(new Runnable() {
@Override
public void run() {
go();
}
});
}
executorService.shutdown();
}
private static void go() {
System.out.println(Thread.currentThread().getName()+"准备就绪");
try {
cyclicBarrier.await();
System.out.println(Thread.currentThread().getName()+"开始执行");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
结果:
5. Semaphore
信号量, 用来限制某种资源的线程数量. 就是只允许这么多的线程使用, 一旦线程数被占满, 后面的线程就等待.
package demo02;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @author Jeady
* @Date 2020/3/9
*/
public class MySemaogore {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
Semaphore semaphore = new Semaphore(10);
for (int i=1;i<=20;i++){
final int index = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
play();
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
executorService.shutdown();
}
private static void play() {
System.out.println(new Date()+""+Thread.currentThread().getName()+"获得资格");
try {
Thread.sleep(2000);
System.out.println(new Date()+""+Thread.currentThread().getName()+"退出服务器");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果:
6. 线程池:
java.util.concurrent.ThreadPoolExecutor 类就是一个线程池。
客户端调ThreadPoolExecutor.submit(Runnable task) 提交任务,线程池内部维护的工作者线程的数量就是该线程池的线程池大小
当前线程池大小 :表示线程池中实际工作者线程的数量;
最大线程池大小 (maxinumPoolSize):表示线程池中允许存在的工作者线程的数量上限;
核心线程大小 (corePoolSize ):表示一个不大于最大线程池大小的工作者线程数量上限。
如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队;
如果运行的线程等于或者多于 corePoolSize,则 Executor 始终首选将请求加入队列,而不是添加新线程;
如果无法将请求加入队列,即队列已经满了,则创建新的线程,除非创建此线程超出 maxinumPoolSize, 在这种情况下,任务将被拒绝。
ThreadPoolExecutor :
核心线程池内部实现了解吗
对于核心的几个线程池,无论是 newFixedThreadPool() 方法,newSingleThreadExecutor() 还是 newCachedThreadPool() 方法,虽然看起来创建的线程有着完全不同的功能特点,
但其实内部实现均使用了 ThreadPoolExecutor 实现,其实都只是 ThreadPoolExecutor 类的封装。
函数的参数含义如下:
corePoolSize:指定了线程池中的线程数量
maximumPoolSize:指定了线程池中的最大线程数量
keepAliveTime:当线程池线程数量超过 corePoolSize 时,多余的空闲线程的存活时间。即,超过了 corePoolSize 的空闲线程,在多长时间内,会被销毁。
unit: keepAliveTime 的单位。
workQueue:任务队列,被提交但尚未被执行的任务。
threadFactory:线程工厂,用于创建线程,一般用默认的即可。
handler:拒绝策略。当任务太多来不及处理,如何拒绝任务。
Scala并发编程:
scala采用消息传递而非资源共享来实现程序的并发,消息传递通过Actor来实现的 (代码后期慢慢会补充上来)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dx3wmitC-1580712528515)(C:\Users\lenovo\AppData\Local\Temp\1580712075925.png)]
务来中断线程。
volatile 关键字:
该关键字可以保证可见性不保证原子性。
Scala并发编程:
scala采用消息传递而非资源共享来实现程序的并发,消息传递通过Actor来实现的 (代码后期慢慢会补充上来)
[外链图片转存中…(img-Dx3wmitC-1580712528515)]