Java多线程深入理解学习笔记之四-----多线程安全问题实现2及之前总结

解决线程安全问题实现2

同步方法

就是把同步关键字加到方法上,同步方法的对象是this,下面是代码:

//自定义线程类
package m8d5;

public class Ticket implements Runnable {
	private int amount = 100;
	private int x = 0;
	//private Object object = new Object();
	@Override
	public void run() {
		while (true) {
			if (x % 2 == 0) {
				synchronized (this) {
					if (amount > 0) {
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println(Thread.currentThread().getName() + "成功卖出第" + amount + "票");
						amount--;
					}
				}	
			} else {
				ticketSell();
			}
			x++;
		}

	}
	public synchronized void ticketSell() {
		if (amount > 0) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "成功卖出第" + amount + "票");
			amount--;
		}
	}

}

//测试类
package m8d5;

public class TicketDemo {
	public static void main(String[] args) {
		Ticket ticket = new Ticket();
		
		Thread threadA = new Thread(ticket, "窗口A");
		Thread threadB = new Thread(ticket, "窗口B");
		Thread threadC = new Thread(ticket, "窗口C");
		
		threadA.start();
		threadB.start();
		threadC.start();
	}
}

如果是静态方法,同步方法的对象是该类的字节码文件,因为是静态方法,所以同步的对象肯定要比静态方法先存在

下面是静态方法的实现方法:

//自定义线程类
package m8d5;

public class Ticket implements Runnable {
	private static int amount = 100;
	private int x = 0;
	@Override
	public void run() {
		while (true) {
			if (x % 2 == 0) {
				synchronized (Ticket.class) {
					if (amount > 0) {
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println(Thread.currentThread().getName() + "成功卖出第" + amount + "票");
						amount--;
					}
				}	
			} else {
				ticketSell();
			}
			x++;
		}

	}
	public static synchronized void ticketSell() {
		if (amount > 0) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "成功卖出第" + amount + "票");
			amount--;
		}
	}

}

//测试类
package m8d5;

public class TicketDemo {
	public static void main(String[] args) {
		Ticket ticket = new Ticket();
		
		Thread threadA = new Thread(ticket, "窗口A");
		Thread threadB = new Thread(ticket, "窗口B");
		Thread threadC = new Thread(ticket, "窗口C");
		
		threadA.start();
		threadB.start();
		threadC.start();
	}
}

如果锁对象是this,就可以考虑使用同步方法。

否则能使用同步代码块的尽量使用同步代码块。

之前的总结

1:多线程(理解)
    (1)多线程:一个应用程序有多条执行路径
        进程:正在执行的应用程序
        线程:进程的执行单元,执行路径
        单线程:一个应用程序只有一条执行路径
        多线程:一个应用程序有多条执行路径
        
        多进程的意义?
            提高CPU的使用率
        多线程的意义?
            提高应用程序的使用率
    (2)Java程序的运行原理及JVM的启动是多线程的吗?
        A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程。
        B:JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程。
    (3)多线程的实现方案(自己补齐步骤及代码    掌握)
        A:继承Thread类
        B:实现Runnable接口
    (4)线程的调度和优先级问题
        A:线程的调度
            a:分时调度
            b:抢占式调度 (Java采用的是该调度方式)
        B:获取和设置线程优先级
            a:默认是5
            b:范围是1-10
    (5)线程的控制(常见方法)
        A:休眠线程
        B:加入线程
        C:礼让线程
        D:后台线程
        E:终止线程(掌握)
    (6)线程的生命周期(参照    线程生命周期图解.bmp)
        A:新建
        B:就绪
        C:运行
        D:阻塞
        E:死亡
    (7)电影院卖票程序的实现
        A:继承Thread类
        B:实现Runnable接口
    (8)电影院卖票程序出问题
        A:为了更符合真实的场景,加入了休眠100毫秒。
        B:卖票问题
            a:同票多次
            b:负数票
    (9)多线程安全问题的原因(也是我们以后判断一个程序是否有线程安全问题的依据)
        A:是否有多线程环境
        B:是否有共享数据
        C:是否有多条语句操作共享数据
    (10)同步解决线程安全问题
        A:同步代码块
            synchronized(对象) {
                需要被同步的代码;
            }
            
            这里的锁对象可以是任意对象。
            
        B:同步方法
            把同步加在方法上。
            
            这里的锁对象是this
            
        C:静态同步方法
            把同步加在方法上。
            
            这里的锁对象是当前类的字节码文件对象(反射再讲字节码文件对象)
    (11)回顾以前的线程安全的类
        A:StringBuffer
        B:Vector
        C:Hashtable
        D:如何把一个线程不安全的集合类变成一个线程安全的集合类
            用Collections工具类的方法即可。

猜你喜欢

转载自blog.csdn.net/acDream_/article/details/81429258