多线程
1.概念杂记
* runnable不叫线程,叫任务
* 继承和接口,一般优先选择接口
* 线程睡眠时会释放cpu
* 后台线程(守护线程)会因前台线程的结束而结束
* 线程优先级1-10,默认5
* 多线程同步机制必须使用同一把锁(即同一个对象)
* 同步方法使用的锁就是调用的对象this
* 多线程用StringBuffer,单线程用StringBuilder
* synchronized既能同步代码块,也能同步方法
* yield()是让出cpu,但是还可以再抢
* static synchronized的锁为类名.class(字节码文件)
* 单例模式安全性和效率解决方法:多重判断
* wait()等待,notify()唤醒
* wait()会释放锁,sleep不会释放锁
* wait()必须放在同步中
* 因为同步锁可以为任意锁或对象,所以wait方法在Object类下
* 同步嵌套同步,发生死锁的概率很大
* 哪个线程执行wait(),哪个线程就等待
2.线程两种启动方法
* 继承Thread类
class MyThread extends Thread{
@Override
public void run() {
XXX;
}
}
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();
}
}
* 实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
XXX;
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread t1 = new Thread(runnable);
t1.start();
}
}
3.多线程
* 继承Thread类
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start();
t2.start();
* 实现Runnable接口
MyRunnable runnable = new MyRunnable();
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
t1.start();
t2.start();
4.线程安全较高效率的单例模式
public class SingleInstance {
private static SingleInstance single;
private SingleInstance(){}//构造方法私有化为了不让别人new
public static SingleInstance getInstance(){
if(single == null){
synchronized (SingleInstance.class) {
if(single == null){
single = new SingleInstance();
}
}
}
return single;
}
}
5.wait方法和sleep方法的区别
* 1:wait方法会释放锁,sleep方法不会释放锁。
* 2:wait必须放在同步中,sleep不一定放在同步中.
* 3:wait一般的情况是让对方唤醒。sleep通常会自己醒过来。
* 4:wait需要用锁去调用。sleep是用Thread类或者Thread对象来调用。
6.Condition
public static Lock lock = new ReentrantLock();
//创建一个Condition
public static Condition p_con = lock.newCondition();
public static Condition c_con = lock.newCondition();
例子:
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length)
putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length)
takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
7.Executors-线程池
ExecutorService service = Executors.newFixedThreadPool(2);
for(int i = 0;i<100;i++){
service.execute(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+i);
}
});
}
8.线程的生命周期
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现