创建线程方式
不浪费时间了自个看嗷
简单说一下吧
1.实现Runnable 接口跟继承 Thread 这个都知道嗷不多bb,如果问你那个好就说实现Runnable 接口,众所周知可以多实现但是只能单继承,这样更灵活
2.线程池写法比着写就行了没啥说的
3.又返回值得线程 线程池使用 Future ,非线程池使用FutureTask然后用Thread 启动,自己看看源码 FutureTask实现自RunnableFuture然后RunnableFuture 实现 Runnable 返回值用get获取就行了。
static class myTh implements Runnable {
@Override
public void run () {
System.out.println("线程");
}
}
static class myThread extends Thread {
@Override
public void run () {
System.out.println("线程");
}
}
static class myCall implements Callable<String> {
@Override
public String call () {
return "返回值";
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//实现Runnable写法
new Thread(new myTh()).start();
//继承Thread写法
new myThread().start();
//线程池写法
ExecutorService service = Executors.newCachedThreadPool();
service.execute(new myTh);
service.submit(new myTh());
//线程池返回值写法
Future<String> future = service.submit(new myCall());
String a = future.get();
//不用线程池来创建又返回值写法
FutureTask<String> futureTask = new FutureTask(new myCall());
new Thread(futureTask).start();
String str = futureTask.get();
}
线程基础
1.什么是程序 cpu的可执行文件
2.什么是进程 一个程序呢可以有多个进程,也可以通过代码实现一个进程,官方点回答就是,最小的分配资源的单位
3.什么是线程 一个进程可以多个线程
线程呐就是进程的执行路径,就比如你写个方法,里面if()else()一个流程下来多线程呢,就是一个进程里面多个线程同时运行
底层角度就是内存交由cpu执行的就是线程 所以是执行单位
4.线程切换
什么是线程切换
看下面一个很low的图嗷
线程组成
指令
数据
cpu 主要就是
PC 存指令的
ALU 计算的
寄存器 存执行的单元的
然后多个线程咋切换呢
先说咋执行的,pc执行指令寄存器数据支持 alu计算
然后呢执行到一段时间通过线程转换算法说要服务下一个线程了 则把数据存到缓存里面,然后拿过新的 线程数据指令来 执行,通过缓存来回切换 好就这样
5.单核cpu设置多线程有意义嘛
有 为什么 说场景嗷 比如一个线程在等待此时不消耗cpu,此时可以先让别的线程执行
6.线程数量是不是越大越好
不是,因为上面说的线程切换是消耗资源的。
7.应该设置多少线程合适呢
看公式嗷
然后说出公式,然后进行工具进行测试找出最优答案,好了就这样
线程状态
- new状态 这个不多说
- runnable 可运行状态
- waiting 等待被唤醒
- timed waiting 计时等待被唤醒 就是设置6秒之后自动唤醒那种
- blocked 被阻塞等待锁
- terminated 线程结束
这几个挑几个重点说一下具体嗷
runnable 可执行状态为两种 running跟ready Thread.yieid时候则ready 当被调度器调度的时候是running
waiting 这个状态呢就是 wait join lockSupport.park Lock.lock 的时候进入 notify notifyall lockSupport.unpark Lock.unlock 接触
timed waiting 则是wait(time) sleep(time) 设置时间 的时间进入,时间结束退出
blocked synchronized当竞争锁没有竞争到的时候
线程的打断 inerrupt
这个打断呢不是真正的打断,这个其实理解为标记更加准确
其中共有三个方法
是thread的方法
puble void inerrupt ()设置标志位
puble boolean isInerrupted () 是否设置标志位 如果没有返回false 反之true
puble static boolean inerrupted () 返回标志位 并重置为false
知识点1
inerrupt 与sleep跟wait跟join 遇到时候则会抛异常,需要处理异常
知识点2
inerrupt 无法中断synchronized跟lock.lock竞争锁的线程
如果需要打断的话则需要
lock.lockInerruptibly 此时在启动线程之后执行 线程.inerrupt 则会中断
优雅的结束线程的方法
先说不优雅的
stop直接结束
suspend resume 暂停跟启动
以上是被弃用的 以为太暴力了,直接结束
第一种 使用volatile 修饰的标识但是前提是在逻
private static volatile boolean runing;
Thread t = new Thread(() -> {
long o = 0L;
while (runing) {
o++;
}
});
Thread.sleep(1000);
t.start();
runing = false;
第二种 就是上面的中断
Thread t = new Thread(() -> {
long o = 0L;
while (!Thread.interrupted()) {
o++;
}
});
Thread.sleep(1000);
t.start();
t.interrupt();
这次先到这了嗷!下一次再发
多线程的
可见性
有序性
原子性