线程创建
继承Thread
public class DemoThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 50; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(i+" "+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
DemoThread t1 = new DemoThread();
DemoThread t2 = new DemoThread();
t1.start();
t2.start();
}
}
实现Runnable接口
public class DemoRunable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 50; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(i+" "+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
Thread t = new Thread(new DemoThread(),"worker-1");
Thread t2 = new Thread(new DemoThread(),"worker-2");
t.start();
t2.start();
}
}
实现Callable接口
public class DemoCallable implements Callable {
@Override
public Integer call() throws Exception {
int i ,sum=0;
for ( i=1; i <=50; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
sum+=i;
System.out.println(i+" "+Thread.currentThread().getName());
}
return sum;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Integer> task = new FutureTask<Integer>(new DemoCallable());
new Thread(task).start();
System.out.println(task.get()); //获取call返回值
}
}
买票实现
package thread_prac;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SellTicket implements Runnable {
int t = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (t > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
lock.lock();
// synchronized (this) {
if (t > 0) {
System.out.println("已卖掉第" + t + "张票 " + Thread.currentThread().getName());
t--;
} else {
return;
}
// }
lock.unlock();
}
}
public static void main(String[] args) {
SellTicket sellTicket = new SellTicket();
Thread t1 = new Thread(sellTicket, "window1");
Thread t2 = new Thread(sellTicket, "window2");
Thread t3 = new Thread(sellTicket, "window3");
Thread t4 = new Thread(sellTicket, "window4");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
线程池创建
package thread_prac;
import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.*;
public class DemoThreadPool {
public static void main(String[] args) {
/**
* corePoolSize 线程池核心线程大小
* maximumPoolSize 线程池最大线程数量
* keepAliveTime 空闲线程存活时间
* unit 空间线程存活时间单位
* workQueue 工作队列
* ①ArrayBlockingQueue 基于数组的有界阻塞队列,按FIFO排序。
* ②LinkedBlockingQuene 基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。
* ③SynchronousQuene 一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。
* ④PriorityBlockingQueue 具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
* threadFactory 线程工厂
* handler 拒绝策略 、
* ①CallerRunsPolicy 该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务
* ②AbortPolicy 该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。
* ③DiscardPolicy 该策略下,直接丢弃任务,什么都不做。
* ④DiscardOldestPolicy 该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列
*/
ExecutorService executorService = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
for (int i = 0; i < 7; i++) {
executorService.execute(new Worker());
}
executorService.shutdown();
// singleThreadPool();
// cacheThreadPool();
// fixedThreadPool();
// scheduleTheadPool();
}
public static void singleThreadPool(){
/**
* 只有一个线程的线程池
* 所有任务都保存队列LinkedBlockingQueue中,核心线程数为1,线程空闲时间为0
* 等待唯一的单线程来执行任务,并保证所有任务按照指定顺序(FIFO或优先级)执行
*/
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
executorService.execute(new Worker());
}
executorService.shutdown();
}
public static void cacheThreadPool(){
/**
* 当任务超过线程池的线程数则创建新线程 可缓存无界限线程池(Integer.MAX_VALUE)
* 空闲线程超过60秒自动回收 核心线程数为0
*/
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i <100; i++) {
executorService.execute(new Worker());
}
executorService.shutdown();
}
public static void fixedThreadPool(){
/**
* 创建指定大小的线程池 超出的线程会在LinkedBlockingQueue阻塞队列中等待
* 核心线程数为可以指定 空闲线程为0
*/
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i <6; i++) {
executorService.execute(new Worker());
}
executorService.shutdown();
}
public static void scheduleTheadPool(){
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
// executorService.schedule(new Worker(),2,TimeUnit.SECONDS); //延迟2秒后执行任务
// executorService.scheduleAtFixedRate(new Worker(),2,3,TimeUnit.SECONDS); //周期性执行任务 当前任务执行时间大于等于间隔时间,任务执行后立即执行下一次任务。相当于连续执行了。
//每当上次任务执行完毕后,间隔一段时间执行。不管当前任务执行时间大于、等于还是小于间隔时间,执行效果都是一样的。
executorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
long start = new Date().getTime();
System.out.println("scheduleWithFixedDelay 开始执行时间:" +
DateFormat.getTimeInstance().format(new Date()));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = new Date().getTime();
System.out.println("scheduleWithFixedDelay执行花费时间=" + (end - start) / 1000 + "m");
System.out.println("scheduleWithFixedDelay执行完成时间:"
+ DateFormat.getTimeInstance().format(new Date()));
System.out.println("======================================");
}
}, 1, 2, TimeUnit.SECONDS);
}
}
class Worker implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " > 开始办理业务... ");
System.out.println(Thread.currentThread().getName() + " >> 正在办理" );
System.out.println(Thread.currentThread().getName() + " >>> 办理结束 ");
}
}
生产者和消费者模型
- wait和notify
package thread_prac;
public class DemoWait {
public static void main(String[] args) {
Account account = new Account();
new Thread(()->{
for (int i = 0; i < 100; i++) {
try {
account.decrement();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"C1").start();
new Thread(()->{
for (int i = 0; i < 100; i++) {
try {
account.decrement();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"C2").start();
new Thread(()->{
for (int i = 0; i < 100; i++) {
try {
account.increment();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"P").start();
}
}
class Account{
public static int money = 0;
public synchronized void increment() throws InterruptedException {
while (money!=0){ //若使用了if 则多个消费者或多个生产者同时运行会产生问题
this.wait();
}
money++;
System.out.println(Thread.currentThread().getName()+"=>"+money);
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException {
while (money==0){
this.wait();
}
money--;
System.out.println(Thread.currentThread().getName()+"=>"+money);
this.notifyAll();
}
}
- await 和signal 这种是随机的
package thread_prac;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class DemoAwait {
public static void main(String[] args) {
Account2 account = new Account2();
new Thread(()->{
for (int i = 0; i < 100; i++) {
try {
account.decrement();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"C1").start();
new Thread(()->{
for (int i = 0; i < 100; i++) {
try {
account.decrement();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"C2").start();
new Thread(()->{
for (int i = 0; i < 100; i++) {
try {
account.increment();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"P").start();
}
}
class Account2 {
public static int money = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void increment() throws InterruptedException {
lock.lock();
try {
while (money != 0) {
condition.await();
}
money++;
System.out.println(Thread.currentThread().getName() + "=>" + money);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void decrement() throws InterruptedException {
lock.lock();
try {
while (money == 0) {
condition.await();
}
money--;
System.out.println(Thread.currentThread().getName() + "=>" + money);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
- Condition精准唤醒 A唤醒B, B唤醒C,C唤醒A
package thread_prac;
import java.util.Date;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class DemoOrderSignal {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.PrintA();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.PrintB();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.PrintC();
}
},"C").start();
}
}
class Data{
int num = 1; //1A 2B 3C
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
public void PrintA(){
lock.lock();
try {
//业务,判断》执行》通知
while (num!=1){
condition1.await();
}
System.out.println(Thread.currentThread().getName()+"=>A");
num = 2;
condition2.signal(); //唤醒B
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void PrintB(){
lock.lock();
try {
while (num!=2){
condition2.await();
}
System.out.println(Thread.currentThread().getName()+"=>B");
num = 3;
condition3.signal(); //通知其他线程 我完成了
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void PrintC(){
lock.lock();
try {
while (num!=3){
condition3.await();
}
System.out.println(Thread.currentThread().getName()+"=>C");
num =1;
condition1.signal(); //通知其他线程 我完成了
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
输出结果
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
...