码迷,mamicode.com
首页 > 移动开发 > 详细

android 线程相关

时间:2020-08-31 13:18:46      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:在线   资源分配   ant   err   tran   通过   rgs   public   sync   

线程

cpu调度的最小单位

进程

进程是程序运行资源分配的最小单位

并发和并行

并行:同一时间能够执行不同任务,4核cpu有四个线程,并行数量就是4,如果超频,并行数量位8

并发: 单位时间内能执行多少不同任务

启动线程的方式

1

Thread thread = new Thread(){
   @Override
   public void run() {
      
   }
};
thread.start();

2

Runnable runnable = new Runnable() {
    @Override
    public void run() {

    }
};
new Thread(runnable).start();

3

Callable<String> callable = new Callable<String>() {
    @Override
    public String call() throws Exception {
        return "test";
    }
};
FutureTask<String> futureTask = new FutureTask<>(callable);
new Thread(futureTask).start();
System.out.println(futureTask.get());// get为阻塞方法
中止

suspend()、resume()和stop()这些方法是操作线程的方法,过时了,不建议用,会导致资源不会被释放

正确中止有三种

interrupt(),协作式,并不会马上中止:

private static class UseThread extends Thread{
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        int i = 0;
        while (true) {
            System.out.println(threadName + i++);
        }
    }
}

public static void main(String[] args) throws Exception {
    UseThread useThread = new UseThread();
    useThread.start();
    Thread.sleep(20);
    useThread.interrupt(); // 这里调用后日志还会继续打印,说明单调用这个方法并不能中断线程
}

配合使用isInterrupted()方法来判断,当调用了interrupt() 后,isInterrupted() 返回true:

private static class UseThread extends Thread{
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        int i = 0;
        while (!isInterrupted()) { // 相当于标识位
            System.out.println(threadName + i++);
        }
        System.out.println("结束了");
    }
}

public static void main(String[] args) throws Exception {
    UseThread useThread = new UseThread();
    useThread.start();
    Thread.sleep(2000);
    useThread.interrupt();
}

还有一个判断的方法interrupted(),会自动再把值改成false

private static class UseThread extends Thread{
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        int i = 0;
        while (!interrupted()) {
            System.out.println(threadName + i++);
        }
        System.out.println("结束了" + isInterrupted()); // false,应为interrupted()会把值再变成false
    }
}

public static void main(String[] args) throws Exception {
    UseThread useThread = new UseThread();
    useThread.start();
    Thread.sleep(2);
    useThread.interrupt();
}
一些其他的方法
start()

让一个线程进入就绪队列等待分配cpu,分到cpu后才调用实现的run()方法,start()方法不能重复调用。

yield()

使当前线程让出CPU占有权,但让出的时间是不可设定的。也不会释放锁资源,所有执行yield()的线程有可能在进入到可执行状态后马上又被执行。

join()

把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

sleep()

sleep方法是是一个静态方法,直接调用可以阻塞当前线程,sleep是不会释放对象锁

wait()

wait方法是object类里面,调用也是阻塞线程,但是会让出锁,通过notify或者notifyAll方法让线程重新进入就绪状态。

graph TD

a(新建) -->|start| b(就绪) 
b-->|join| c(运行)
f-->|时间到或者interrupt| b
c -->|yield| b
c--> |sleep|f(阻塞)
c -->d(结束)
c --> |wait| e(阻塞)
e -->|notity或者notifyAll| b


synchronized

java的内置锁

  • 锁普通方法锁的是this当前对象
  • 锁静态方法锁的是当前类
  • 代码块里要看锁的是new出来的对象还是class
lock

显式锁

  • RenentrantLock

可重入锁,会判断持有锁的是不是当前持有锁的线程,如果是,可以重新取得锁,例如一些递归的操作

RenentrantLock的标准用法:

ReentrantLock lock = new ReentrantLock();

lock.lock();
try{
    
}finally{
    // 一定要在finally代码块中释放锁,不然会导致资源不被释放
    lock.unlock();
}
  • ReentrantReadWriteLock

可重入读写锁,读的时候如果没有写线程持有锁,那么可以允许多个读线程持有锁但不允许写线程持有锁;如果有写线程持有锁,那么不允许读线程持有锁,只能有一个写线程持有锁。

android 线程相关

标签:在线   资源分配   ant   err   tran   通过   rgs   public   sync   

原文地址:https://www.cnblogs.com/youfat/p/13559855.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!