java之11天 多线程 (二)

本文探讨了线程安全问题,包括使用同步代码块和同步函数解决卖票系统的并发问题,并介绍了如何避免死锁的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=medium][b]卖票安全问题 [/b][/size]

[b]//线程出现安全问题啦 !!! 卖出了 0 -1 -2 号票了[/b]


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--);
}
}
}

}


[b]//使用 synchronized 同步代码块 来解决 [/b]

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--);
}
}
}
}

}


[b]//使用 synchronized 同步函数 来解决 [/b]

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--);
}
}

}



[b] * 同步函数 用的是那一个锁呢 .????(this 锁)[/b]

/**
*
* 函数需要被对象调用, 那么函数都一个所属对象的引用,就是 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--);
}
}

}



[b]main Test[/b]

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个 来测试 .
}

}


[size=medium][b]静态同步函数 (Class 锁)[/b][/size]


/**
* 如果同步函数被静态就是后,使用的锁是什么呢?
* 通过验证,发现 不在是 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();

}

}


[size=medium][b]单例模式[/b][/size]

/**
* 单例模式
*
* //饿汉式
* 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();
}

}



[size=medium][b]死锁1[/b][/size]

/**
* 死锁
* 通常,是同步中嵌套同步,但是锁不同
*
*/

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();
}

}


[size=medium][b]死锁2[/b][/size]

**
* 请写一个简单的死锁例子
*/
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();
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值