卖票安全问题
//线程出现安全问题啦 !!! 卖出了 0 -1 -2 号票了
class SaleTicket1 implements Runnable{
private int ticks=100;
private long time=1000; //加上这个后 就让安全问题 跟明显了
public void run(){ //复写接口中的方法 ,不能抛异常 ,只能try
while(true){
if(ticks>0){
try {
if(time>0){
Thread.currentThread().sleep(time);
time=time-200;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
}
//使用 synchronized 同步代码块 来解决
class SaleTicket2 implements Runnable{
private int ticks=100;
private long time=1000; //加上这个后 就让安全问题 跟明显了
Object obj=new Object();
public void run(){ //复写接口中的方法 ,不能抛异常 ,只能try
while(true){
synchronized(obj){ //同步代码块 obj :称为锁
if(ticks>0){
try {
if(time>0){
Thread.currentThread().sleep(time);
time=time-200;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
}
}
//使用 synchronized 同步函数 来解决
class SaleTicket3 implements Runnable{
private int ticks=100;
private long time=1000; //加上这个后 就让安全问题 跟明显了
//Object obj=new Object();
public void run(){ //复写接口中的方法 ,不能抛异常 ,只能try
while(true){
//synchronized(obj){ //同步代码块 obj :称为锁
this.show();
//}
}
}
//同步函数 来解决
public synchronized void show(){
if(ticks>0){
try {
if(time>0){
Thread.currentThread().sleep(time);
time=time-200;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
* 同步函数 用的是那一个锁呢 .????(this 锁)
/**
*
* 函数需要被对象调用, 那么函数都一个所属对象的引用,就是 this
* 所以同步函数使用的锁是 this
*
* 通过程序来进行验证 同步函数使用的是 this
*
* 使用两个程序来买票
* 一个线程在不同步代码快找那个
* 一个线程在同步函数中
* 都在执行买票动作.
*
*/
class SaleTicket implements Runnable{
private int ticks=1000;
private long time=10; //加上这个后 就让安全问题更明显了
Object obj=new Object();
boolean flag=true;
public void run(){ //复写接口中的方法 ,不能抛异常 ,只能try
if(flag){
while(true){
/**
* 发现 使用 obj 的时候 卖出的票 出现了 0 -1 -2 ,说明同步没有成功,
* 找原因发现, 不满足线程同步第二个条件, 就是使用的不是同一个锁,
* 把 obj 换成 this 试试 发现 结果正确了 由此
*
*/
synchronized(this){ //obj -->this
if(ticks>0){
try {
if(time>0){
Thread.currentThread().sleep(time);
///time=time-200;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
}else
while(true)
this.show();
}
/*
* 同步函数 用的是那一个锁呢 .
*
* 函数需要被对象调用, 那么函数都一个所属对象的引用,就是 this
* 所以同步函数使用的锁是 this
*
*/
public synchronized void show(){
if(ticks>0){
try {
if(time>0){
Thread.currentThread().sleep(time);
//time=time-200;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
main Test
public class ThreadDemo1 {
public static void main(String[] args) {
SaleTicket t1=new SaleTicket();
Thread th1=new Thread(t1); //创建了一个线程 并将Runnable 子类对象给 Thread 构造函数
Thread th2=new Thread(t1);
//Thread th3=new Thread(t1);
//Thread th4=new Thread(t1);
th1.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.flag=false;
th2.start();
//th3.start();
//th4.start();
//测试 同步函数使用的锁时候 ,只需要用 两个线程就可以了 其他的 4个 来测试 .
}
}
静态同步函数 (Class 锁)
/**
* 如果同步函数被静态就是后,使用的锁是什么呢?
* 通过验证,发现 不在是 this ,因为静态中不可以定义 this
*
* 静态进内存是,内存中没有本类对象,但是一定有该类对应的字节码文件对象
* 类名.class 该对象的类型是Class
*
* 通过下面的测试 发现
* 静态的同步方法,使用的锁是该方法所在类的字节码文件对象, 类名 .calss
*
*/
class SaleTicket implements Runnable{
private static int ticks=1000;
private static long time=10; //加上这个后 就让安全问题更明显了
//Object obj=new Object();
boolean flag=true;
public void run(){ //复写接口中的方法 ,不能抛异常 ,只能try
if(flag){
while(true){
synchronized(SaleTicket.class){ //obj(不安全卖出了 0 号票) -->this(不安全卖出了 0 号票)--->SaleTicket.calss (安全了 发现从此没有卖出 0号票了)
if(ticks>0){
try {
if(time>0){
Thread.currentThread().sleep(time);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
}else
while(true)
this.show();
}
//静态 同步方法
public static synchronized void show(){
if(ticks>0){
try {
if(time>0){
Thread.currentThread().sleep(time);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
public class ClassLoaclDemo {
public static void main(String[] args) {
SaleTicket t1=new SaleTicket();
Thread th1=new Thread(t1); //创建了一个线程 并将Runnable 子类对象给 Thread 构造函数
Thread th2=new Thread(t1);
th1.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.flag=false;
th2.start();
}
}
单例模式
/**
* 单例模式
*
* //饿汉式
* class Single{
* private static final Single s=new Single();
* private Single();
* public static Single getInstance(){
* return s;
* }
* }
*
*
* //懒汉式
* class Single{
* private static Single s=null;
* private Single(){}
* public static Single getInstance(){
* if(s=null)
* s=new Single();
* return s;
* }
*
*
*
* }
*
*
*
*/
//懒汉式 加入 同步 效率比较低效
class Single{
private static Single s=null;
private Single(){}
//使用 同步函数
public static synchronized Single getInstance1(){
if(s==null)
s=new Single();
return s;
}
//使用 同步代码快
public static Single getInstance(){
if(s==null){ //使用双重判断 增加 懒汉式 的效率
synchronized(Single.class){
if(s==null)
s=new Single();
}
}
return s;
}
}
public class SingleDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Single s =Single.getInstance();
}
}
死锁1
/**
* 死锁
* 通常,是同步中嵌套同步,但是锁不同
*
*/
class SaleTicket implements Runnable{
private int ticks=1000;
private long time=10;
Object obj=new Object();
boolean flag=true;
public void run(){
if(flag){
while(true){
synchronized(obj){ //同步代码块 里面有同步 函数
show(); //this
}
}
}else
while(true)
this.show(); //this
}
//同步函数里面有 同步代码块
public synchronized void show(){//使用的是 this
synchronized(obj){ //这里确使用的 obj
if(ticks>0){
try {
if(time>0){
//Thread.sleep(time);
Thread.currentThread().sleep(time);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
}
}
}
}
public class DeadLocalDemo {
public static void main(String[] args) {
SaleTicket t1=new SaleTicket();
Thread th1=new Thread(t1); //创建了一个线程 并将Runnable 子类对象给 Thread 构造函数
Thread th2=new Thread(t1);
//Thread th3=new Thread(t1);
//Thread th4=new Thread(t1);
th1.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.flag=false;
th2.start();
//th3.start();
//th4.start();
}
}
死锁2
**
* 请写一个简单的死锁例子
*/
class Test implements Runnable{
private boolean flag;
Test(boolean flag){
this.flag=flag;
}
public void run(){
if(flag){
synchronized (MyLock.locka) {
System.out.println("if locka");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (MyLock.lockb) {
System.out.println("if lockb");
}
}
}else{
synchronized (MyLock.lockb) {
System.out.println("else lockb");
synchronized (MyLock.locka) {
System.out.println("else locka");
}
}
}
}
}
class MyLock{
static Object locka=new Object();
static Object lockb=new Object();
}
public class DeadLocalTest {
public static void main(String[] args) {
Thread t1=new Thread(new Test(true));
Thread t2=new Thread(new Test(false));
t1.start();
t2.start();
}
}