线程 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 TDa(新建) -->|start| b(就绪) b-->|join| c(运行)f-->|时间到或者interrupt| bc -->|yield| bc--> |sleep|f(阻塞)c -->d(结束)c --> |wait| e(阻塞)e -->|notity或者notifyAll| b锁synchronizedjava的内置锁 - 锁普通方法锁的是this当前对象
- 锁静态方法锁的是当前类
- 代码块里要看锁的是new出来的对象还是class
lock显式锁 可重入锁,会判断持有锁的是不是当前持有锁的线程,如果是,可以重新取得锁,例如一些递归的操作 RenentrantLock的标准用法: ReentrantLock lock = new ReentrantLock();lock.lock();try{ }finally{ // 一定要在finally代码块中释放锁,不然会导致资源不被释放 lock.unlock();}可重入读写锁,读的时候如果没有写线程持有锁,那么可以允许多个读线程持有锁但不允许写线程持有锁;如果有写线程持有锁,那么不允许读线程持有锁,只能有一个写线程持有锁。 有相同爱好的可以进来一起讨论哦:企鹅群号:1046795523
|