线程控制
-
线程结束
-
线程合并
先执行合并过来的,主线程等它执行完,再执行主线程
-
线程让位
使当前线程从执行状态(运行状态)百年未可执行态(就绪状态)
-
静态方法,写在谁里面,谁让位
-
同优先级让位,不同优先级不让位
-
-
线程的同步
-
给方法加修饰符synchronized,让该方法变成同步方法。
-
当执行加锁的成员方法时,该对象中其他加锁的成员方法也被锁住
-
当执行加锁的静态方法,该类中其他加锁的静态方法,也被锁住
public synchronized void m1(){ /// }
-
-
同步代码块
-
synchronized(this){} 写在成员方法中,括号中写this
-
synchronized(类名.class){} 写在静态方法中,括号内写类名.class
-
当执行synchronized(this){}代码块时,该对象其他加锁的成员方法和加锁的代码块都被锁住
-
当执行synchronized(类名.class){}代码块时,该类其他加锁的静态方法和加锁的代码块都被锁住
synchronized(对象){ }
-
-
注意:
-
必须保证使用一个资源的多个线程共用一把锁
-
一个线程类中的所有静态方法共用同一把锁(类名.class),所有非静态方法共同一个所(this),同步代码块(指定需谨慎)
-
-
-
Lock显示锁
-
Lock lock = new ReentrantLock();
-
lock.lock();
-
lock.unlock();
synchronized与Lock的对比
-
Lock是显示锁(手动开启和关闭锁,别忘记关锁),synchronized是隐式锁,出了作用域自动释放
-
Lock只有代码块锁,synchronized有代码块锁和方法锁
-
使用Lock锁,JVM将花费更少的时间来调度线程,性能更高。并且具有更好的扩展性(提供更多的子类)。
-
-
Timer定时器
-
先建任务类,继承TimerTask
-
相当于开启一个子线程
参数部分:
-
你要做什么
-
你要在什么时候做:1000~1s之后
-
你隔多长时间做一次: 1000~1s之后
-
-
-
死锁
-
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方需要的同步资源,就形成了线程的死锁
-
出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续
解决方法:
-
专门的算法、原则
-
尽量减少同步资源的定义
-
尽量避免嵌套同步
-
-
线程通信
wait()与notify()和notifyAll()
-
wait():令当前线程挂起并放弃CPU、同步资源并等待,使别的线程可访问并修改共享资源,而当线程排队等待其他线程调用notify()或notifyAll()方法唤醒,唤醒后等待重新获得对监视器的所有权后才能继续执行
-
notify():唤醒当前排队等待同步资源的线程中优先级最高者结束等待
-
notifyAll():唤醒正在排队等待资源的所有线程结束等待
-
wait():
没有传参或者传0,表示不会自己醒,如果有大于0的传参,到时间自己醒,并且会自动释放锁
-
notify():
随机唤醒该对象中的一个wait状态的线程
-
notifyAll():
唤醒该对象中的所有线程
-