1.多线程的创建
(1)继承Thread类
public class MyThread extends Thread{
@Override
public void run(){
for (int i = 0; i < 5; i++) {
System.out.println("子线程执行次数:"+i);
}
}
}
/*
多线程的创建方式1:继承Thead类的实现
*/
public class ThreadDemo1 {
public static void main(String[] args) {
//new一个新线程对象
Thread t = new MyThread();
//调用start方法启动线程(执行的还是run方法)
t.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程执行输出:"+i);
}
}
}
(2)实现Runnable接口
public class MyThreadDemo2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程执行输出:"+i);
}
}
}
public static void main(String[] args) {
//创建任务对象
Runnable runnable = new MyThreadDemo2();
//把任务对象交给Thread处理
Thread t = new Thread(runnable);
//启动线程
t.start();
}
(3)JDK5.0提供了Callable和FutrueTask来实现
public class MyThreadDemo3 implements Callable<String> {
private int n;
public MyThreadDemo3(int n){
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 1; i <= n ; i++) {
sum += i;
}
return "子线程执行的结果是:"+sum;
}
}
public class ThreadDemo3 {
public static void main(String[] args){
Callable<String> call = new MyThreadDemo3(100);
FutureTask<String> futureTask = new FutureTask<>(call);
Thread t = new Thread(futureTask);
t.start();
try {
String s1 = futureTask.get();
System.out.println(s1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
三种方法对比
2.Thread类的常用方法
3.线程安全
package com.itwpf.d3_thread_safe;
public class ThreadDemo {
public static void main(String[] args) {
Account account = new Account("id_card_01",10000);
new DrawThread(account,"小红").start();
new DrawThread(account,"小明").start();
}
}
package com.itwpf.d3_thread_safe;
public class Account {
private String id;
private double money;
public Account() {
}
public Account(String id, double money) {
this.id = id;
this.money = money;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id='" + id + '\'' +
", money=" + money +
'}';
}
public void drawMoney(double money) {
String name = Thread.currentThread().getName();
if(this.money>=money){
System.out.println(name+"来取钱,吐出"+money);
this.money -= money;
System.out.println("最后剩余:"+this.money);
}else{
System.out.println("余额不足");
}
}
}
package com.itwpf.d3_thread_safe;
public class DrawThread extends Thread{
private Account acc;
public DrawThread(Account acc){
this.acc = acc;
}
public DrawThread(Account acc, String name) {
super(name);
this.acc = acc;
}
@Override
public void run() {
acc.drawMoney(10000);
}
}
4.线程同步
(1)加锁方式1:同步代码块
//在类Account的核心方法drawMony中加锁
public void drawMoney(double money) {
String name = Thread.currentThread().getName();
synchronized(this){
if(this.money>=money){
System.out.println(name+"来取钱,吐出"+money);
this.money -= money;
System.out.println("最后剩余:"+this.money);
}else{
System.out.println("余额不足");
}
}
}
(2)加锁方式2:同步方法
public synchronized void drawMoney(double money) {
String name = Thread.currentThread().getName();
if(this.money>=money){
System.out.println(name+"来取钱,吐出"+money);
this.money -= money;
System.out.println("最后剩余:"+this.money);
}else{
System.out.println("余额不足");
}
}
(3)加锁方式3:Lock锁
public void drawMoney(double money) {
String name = Thread.currentThread().getName();
lock.lock();//上锁
try{
if(this.money>=money){
System.out.println(name+"来取钱,吐出"+money);
this.money -= money;
System.out.println("最后剩余:"+this.money);
}else{
System.out.println("余额不足");
}
}finally {
lock.unlock();//解锁
}
}
5.线程通信
package com.itheima.d7_thread_comunication;
/**
呼叫系统。
*/
public class CallSystem {
// 定义一个变量记录当前呼入进来的电话。
public static int number = 0; // 最多只接听一个。
/* 接入电话
*/
public synchronized static void call() {
try {
number++;
System.out.println("成功接入一个用户,等待分发~~~~");
// 唤醒别人 : 1个
CallSystem.class.notify();
// 让当前线程对象进入等待状态。
CallSystem.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
分发电话
*/
public synchronized static void receive() {
try {
String name = Thread.currentThread().getName();
if(number == 1){
System.out.println(name + "此电话已经分发给客服并接听完毕了~~~~~");
number--;
// 唤醒别人 : 1个
CallSystem.class.notify();
CallSystem.class.wait(); // 让当前线程等待
}else {
// 唤醒别人 : 1个
CallSystem.class.notify();
CallSystem.class.wait(); // 让当前线程等待
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.itheima.d7_thread_comunication;
public class CallThread extends Thread{
@Override
public void run() {
// 不断的打入电话
while (true){
CallSystem.call();
}
}
}
package com.itheima.d7_thread_comunication;
/**
接电话线程类
*/
public class ReceiveThread extends Thread{
@Override
public void run() {
// 1号 2号
while (true){
CallSystem.receive();
}
}
}
package com.itheima.d7_thread_comunication;
public class TestDemo {
public static void main(String[] args) {
// 1、生产者线程:负责不断接收打进来的电话
CallThread call = new CallThread();
call.start();
// 2、消费者线程:客服,每个客服每次接听一个电话
ReceiveThread r1 = new ReceiveThread();
r1.start();
}
}
6.线程池
(1)概述
(2)常用API、参数说明
ExecutorService pool = new ThreadPoolExecutor(
3,
5,
6,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy() );
(3)线程池处理Runnable任务
ExecutorService pool = new ThreadPoolExecutor(
3,
5,
6,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy() );
pool.execute(new MyRunnable());
结果
pool-1-thread-1子线程0
pool-1-thread-1子线程1
pool-1-thread-1子线程2
pool-1-thread-1子线程3
pool-1-thread-1子线程4
本任务已休眠pool-1-thread-1
(4)线程池处理Callable任务
ExecutorService pool = new ThreadPoolExecutor(
3,
5,
6,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy() );
//pool.execute(new MyRunnable());
Future<String> submit0 = pool.submit(new MyCallable(100));
Future<String> submit1 = pool.submit(new MyCallable(5));
Future<String> submit2 = pool.submit(new MyCallable(10));
Future<String> submit3 = pool.submit(new MyCallable(20));
Future<String> submit4 = pool.submit(new MyCallable(30));
Future<String> submit5 = pool.submit(new MyCallable(40));
Future<String> submit6 = pool.submit(new MyCallable(50));
String rs = submit0.get();
System.out.println(rs);
System.out.println(submit1.get());
System.out.println(submit2.get());
System.out.println(submit3.get());
System.out.println(submit4.get());
System.out.println(submit5.get());
System.out.println(submit6.get());
结果:
pool-1-thread-1线程返回的结果是:5050(执行1到100)
pool-1-thread-2线程返回的结果是:15(执行1到5)
pool-1-thread-3线程返回的结果是:55(执行1到10)
pool-1-thread-2线程返回的结果是:210(执行1到20)
pool-1-thread-1线程返回的结果是:465(执行1到30)
pool-1-thread-2线程返回的结果是:820(执行1到40)
pool-1-thread-1线程返回的结果是:1275(执行1到50)
(5)Executors工具类实现线程池
7.定时器
public class TimeDemo1 {
public static void main(String[] args) {
//创建定时器
Timer timer = new Timer();//定时器本身就是一个线程
//调用方法,处理定时任务
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行A "+new Date());
}
},0,2000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行B "+new Date());
}
},0,2000);
}
}
public class TimeDemo2 {
public static void main(String[] args) {
//创建ScheduledExecutorService线程池,做定时器
ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
//开启定时器任务
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行输出AAA "+new Date());
}
},0,2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行输出AAA "+new Date());
}
},0,2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行输出bbb "+new Date());
}
},0,2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行输出ccc "+new Date());
}
},0,2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行输出ddd "+new Date());
}
},0,2, TimeUnit.SECONDS);
}
}
8.生命周期