1>多线程的 实现方式 继承Thread类 或者 实现 Runnable 接口
2>出现线程安全的原因(主要讲解 同步锁)
线程 操作共性数据的多条代码 分开执行,就会引起线程安全问题(关键点:存在共性数据,操作共性数据的多条代码被分开)
解决方案:保证 操作共性数据的多条代码在同一时间段内 只有一个线程在执行,执行期间,不允许其他线程进入。
解决问题的方式:
Java提供了解决方案,就是同步机制。
代码体现:同步代码块。
synchronized(对象)//对象可以是任意对象。
{
需要被同步封装的语句。
}
同步的好处:
解决了多线程的安全问题。
同步前提:
1,必须要有两个或者两个以上的线程。
2,多个线程必须使用同一个锁。
同步的弊端:
降低运行效率,对资源是一种消耗。
- class Ticket implements Runnable{
- private int tickets = 10;
- private Object obj = new Object();
- public void run(){
- while(tickets > 0){
- try {
- synchronized(obj){
- Thread.sleep(100);
- if(tickets>0)
- System.out.println(Thread.currentThread().getName()+" "+tickets--);
- }
- } catch (InterruptedException e) {
- throw new RuntimeException();
- }
- }
- }
- }
- public class TicketDemo {
- public static void main(String[] args) {
- Ticket t = new Ticket();
- Thread t1 = new Thread(t);
- Thread t2 = new Thread(t);
- Thread t3 = new Thread(t);
- Thread t4 = new Thread(t);
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
将同步代码块 提取出来 封装为一个方法,同时在该方法 同步(添加synchronized关键字),于是就出现了同步函数。
同步代码块的锁 是 private Object obj = new Object();
同步函数用的锁 是 this。
同步函数和同步代码块的区别:
同步函数使用的锁是固定的 this。
同步代码块可以指定任意的对象作为锁。
一般开发常用同步代码块。
静态同步函数锁使用的锁是:所属类的字节码文件对象 写法 类名.class
验证 使用的 锁 是什么的 方法如下,将同步代码块的锁
- class Ticket implements Runnable
- {
- private int ticks = 100;
- Object obj = new Object();
- boolean flag = true;
- public void run()
- {
- if(flag)
- while(true)
- {
- synchronized(this)
- {
- if(ticks>0)
- {
- try{Thread.sleep(10);}catch(InterruptedException e){}
- System.out.println(Thread.currentThread().getName()+"..code.."+ticks--);
- }
- }
- }
- else
- while(true)
- show();
- }
- public synchronized void show()
- {
- if(ticks>0)
- {
- try{Thread.sleep(10);}catch(InterruptedException e){}
- System.out.println(Thread.currentThread().getName()+"..show funciton.."+ticks--);
- }
- }
- }
- class ThisLockDemo
- {
- public static void main(String[] args)
- {
- Ticket t = new Ticket();
- Thread t1 = new Thread(t);
- Thread t2 = new Thread(t);
- t1.start();
- try{Thread.sleep(10);}catch(Exception e){}
- t.flag = false;
- t2.start();
- }
- }
3>关于 死锁的 一个例子
- class DeadLock implements Runnable{
- private static Object lockA = new Object();
- private static Object lockB = new Object();
- private boolean flag;
- DeadLock(boolean flag){
- this.flag = flag;
- }
- public void run() {
- if(flag){
- while(true){
- synchronized (lockA) {
- System.out.println(" if ------- lockA ");
- synchronized (lockB) {
- System.out.println(" if ------- lockB ");
- }
- }
- }
- }else{
- while(true){
- synchronized (lockB) {
- System.out.println(" else ------- lockB ");
- synchronized (lockA) {
- System.out.println(" else ------- lockA ");
- }
- }
- }
- }
- }
- }
- public class DeadLockDemo {
- public static void main(String[] args) {
- DeadLock t1 = new DeadLock(true);
- DeadLock t2 = new DeadLock(false);
- Thread tt1 = new Thread(t1);
- Thread tt2 = new Thread(t2);
- tt1.start();
- tt2.start();
- }
- }
注意上面代码中使用的锁,是static的,保证t1和t2使用的是相同的 lockA和lockB