Day17 线程(二)
创建多线程方式二:通过实现的方法
1.创建一个实现了Runnable接口的类。
2.实现接口的抽象方法。
3.创建一个Runnable接口实现类的对象。
4.将此对象作为形参传递给Thread类的构造器中,创建Thread类的对象,此对象即为一个线程。
5.调用start()方法,启动线程并执行run()方法。
多线程:
多线程的优点:
1.提高应用程序的相应。对图形化界面更有意义,可增强用户体验。
2.提高计算机系统CPU的利用率。
3.改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改。
线程的生命周期:
线程安全问题:
1.线程安全问题存在的问题?
由于一个线程操作共享数据过程中,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在了安全问题。
2.如何解决线程的安全问题?
必须让一个线程操作共享数据完毕以后,其他线程才有机会参与共享数据的操作。
3.java实现线程的安全:线程的同步机制
方式一:同步代码块
synchronized(同步监视器){
//需要被同步的代码块(即为操作共享数据的代码)
}
1.共享数据:多个线程共同操作的同一个数据(变量)
2.同步监视器:由一个类的对象来充当。哪个线程获取此监视器。谁就可以执行上述被同步的代码。俗称:锁
要求所有的线程使用同一把锁!
在现实的方法中,考虑同步的话,可以使用this来充当锁,但是使用继承的方法时,慎用this!
方法二:将操作共享数据的方法声明为synchronized。即此方法为同步方法,能够保证当其中一个线程执行此方法时,其他线程在外等待直到此线程执行完此方法。
>同步方法的锁:this
4.线程同步的弊端:由于同一个时间只能有一个线程访问共享数据,效率变低。
释放锁的操作:
①当前线程的同步方法、同步代码块的执行结束。
②当前线程再同步代码块、同步方法中遇到break、return终止了该代码块、该方法的继续执行。
③当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束。
④当前线程在同步代码块、同步方法中执行了线程对象的wait(),当前线程暂停,并释放锁。
不会释放锁的操作:
①线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行。
②线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁。
线程的死锁:
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。
-->解决方法:
①专门的算法、原则。
②尽量减少同步资源的定义。
线程的通信:
wait():令当前线程挂起并释放CPU、同步资源,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问。
notif():唤醒正在排队等待同步资源的线程中优先级最高者结束等待。
notifyAll():唤醒正在排队等待同步资源的所有线程结束等待。
Java.lang.Object提供的这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则回报java.lang.illegalMonitorStateException异常。