关于多线程的问题

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


你可能感兴趣的:(关于多线程的问题)