线程
是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
目录
1.多线程的创建
方式一:继承Thread类
//多线程创建方式一:继承Thread类实现
public class ThreadDemo1 {
//main方法启动了一个主线程
public static void main(String[] args) {
Thread myThread = new MyThread();
//调用start方法启动线程
myThread.start();
for (int i = 0; i < 5; i++) {
System.out.print("主线程:"+i+" ");
}
}
}
//定义一个线程类继承Thread类
class MyThread extends Thread{
//继承run方法
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.print("子线程:"+i+" ");
}
}
}
注意事项:
方式二:实现Runnable接口
//线程的创建方式二:
public class ThreadDemo2 {
public static void main(String[] args) {
//创建任务对象
Runnable runnable = new MyRunnable();
//把任务对象交给线程对象
new Thread(runnable).start();
for (int i = 0; i < 10; i++) {
System.out.print("主线程:"+i+" ");
}
}
}
//定义一个线程任务类
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.print("子线程:"+i+" ");
}
}
}
优缺点:
方式三:jdk 5.0 新增:实现Callable接口
//线程创建的方式三:实现Callable,结合FutureTask完成
public class ThreadDemo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建任务对象
Callable<String> myCallable = new MyCallable(100);
//把Callable任务对象 交给 FutureTask对象
//FutureTask实现了runnable对象,封装后可以交给Thread
FutureTask<String> task = new FutureTask<>(myCallable);
//
Thread thread = new Thread(task);
thread.start();
Callable<String> myCallable2 = new MyCallable(200);
//把Callable任务对象 交给 FutureTask对象
//FutureTask实现了runnable对象,封装后可以交给Thread
FutureTask<String> task2 = new FutureTask<>(myCallable2);
//
Thread thread2 = new Thread(task2);
thread2.start();
String s = task.get();
System.out.println("第一个线程结果:"+s);
String s1 = task2.get();
System.out.println("第一个线程结果:"+s1);
}
}
//定义任务类 声明线程任务执行完毕后返回值
class MyCallable implements Callable<String>{
private int n;
public MyCallable(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;
}
}
三种方式的对比
2.Thread的常用方法
//setName() getName() currentThread()
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.setName("设置一号的名字");
t1.start();
MyThread t2 = new MyThread();
t2.start();
Thread m = Thread.currentThread();
System.out.println(m.getName());//主线程就叫main
for (int i = 0; i < 5; i++) {
System.out.println("main线程输出");
}
}
}
public class ThreadDemo02 {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; i++) {
System.out.println("输出:"+i);
if (i==3){
Thread.sleep(3000);
}
}
}
}
3.线程安全
if (this.money >= money) {
System.out.println(name + "来取钱成功,取出" + money);
this.money -= money;
System.out.println(name + "取钱后" + this.money);
} else {
System.out.println(name + "来取钱,余额不足");
}
4.线程同步
方式一:同步代码块
synchronized (this) {
if (this.money>=money){
System.out.println(name+"来取钱成功,取出"+money);
this.money-=money;
System.out.println(name+"取钱后"+this.money);
}else {
System.out.println(name+"来取钱,余额不足");
}
}
方式二:同步方法
方式三:Lock锁
private final Lock lock = new ReentrantLock();
5.线程通信
6.线程池
1.线程池概述
2.线程池实现的API、参数说明
3.线程池处理Runnable任务
//自定义一个线程池对象并测试
public class ThreadPoolDemo1 {
public static void main(String[] args) {
//1.创建线程池对象
ThreadPoolExecutor pool = new ThreadPoolExecutor(
3,
5,
6,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
//2.给任务线程池处理
Runnable runnable = new MyRunnable();
pool.execute(runnable);
pool.execute(runnable);
pool.execute(runnable);
pool.execute(runnable);
pool.execute(runnable);
}
}
4.线程池处理Callable任务
//自定义一个线程池对象并测试
public class ThreadPoolDemo2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1.创建线程池对象
ThreadPoolExecutor pool = new ThreadPoolExecutor(
3,
5,
6,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
//2.给任务线程池处理
Future<String> f1 = pool.submit(new MyCallable(100));
Future<String> f2 = pool.submit(new MyCallable(100));
Future<String> f3 = pool.submit(new MyCallable(100));
Future<String> f4 = pool.submit(new MyCallable(100));
Future<String> f5 = pool.submit(new MyCallable(100));
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
System.out.println(f4.get());
System.out.println(f5.get());
}
}
5.Executors工 具类实现线程池
//使用Executor工具类直接得到一个线程池对象
public class ThreadPoolDemo3 {
public static void main(String[] args) {
//1.创建线程池对象
ExecutorService pool = Executors.newFixedThreadPool(3);
//2.给任务线程池处理
Runnable runnable = new MyRunnable();
pool.execute(runnable);
pool.execute(runnable);
pool.execute(runnable);
pool.execute(runnable);
pool.execute(runnable);
}
}
7.定时器
//timer定时器的使用和了解
public class TimerDemo1 {
public static void main(String[] args) {
Timer timer = new Timer();//定时器本身就是一个单线程
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行一次");
}
},3000,2000);//延时调度 周期调度
}
}
// ScheduledExecutorService定时器的使用和了解
public class TimerDemo2 {
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()+"执行输出:A");
}
},0,2,TimeUnit.SECONDS);
}
}
8.声明周期、并发并行