java多线程2(线程安全与同步)

线程安全

  • 原因:由于一个线程在操作共享数据过程中,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在安全问题
  • 解决方式:必须让一个线程操作共享数据完毕之后,其他线程才有机会参与共享数据操作
  • java解决线程安全:线程的同步机制
    • 同步代码块
	synchronized(同步监视器){
		//需要被同步的代码块(即为操作共享数据的代码)
	}

上篇的代码可改为:

public class testThread{
        
    public static void main(String [] args) {
        
        window window = new window();
        Thread thread1 = new Thread(window);
        Thread thread2 = new Thread(window);
        Thread thread3 = new Thread(window);
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");
        thread1.start();
        thread2.start();
        thread3.start();
        }
    }

class window implements Runnable{
    int tickets = 100;
    Object obj= new Object();
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            synchronized (obj) {//同步监视器(锁)可以用任意类的实例来充当
                if(tickets>0){
                    System.out.println(Thread.currentThread().getName()+":卖出第"+tickets+"张票");
                    tickets=tickets-1;
                }
            }
        } 
    }      
}
public class sellTicket {
    
    public static void main(String [] args){
        window window1 = new window();
        window window2 = new window();
        window window3 = new window();
        window1.setName("窗口1");
        window2.setName("窗口2");
        window3.setName("窗口3");
        window1.start();
        window2.start();
        window3.start();
    }
}
   
class window extends Thread{
    
    public static int tickets = 100;
    static Object obj=new Object();//所有线程共用一把锁,此处用static
    @Override
    public void run() {
        
        while(true){
            synchronized (obj) {
                if(tickets>0){
                    System.out.println(Thread.currentThread().getName()+":卖出第"+tickets+"张票");
                    tickets=tickets-1;
                }else{
                    break;
                }
            }
        }
    }
}

注意:锁只能用同一个,所以继承的方式要用static。

  • 同步方法
    将操作共享数据的方法声明为synchronized,即此方法为同步方法,能够保证当其中一个线程执行此方法时,其他线程在外等待直至此线程执行完此方法。
    同步方法的锁,this
public class testThread{
        
    public static void main(String [] args) {
        
        window window = new window();
        Thread thread1 = new Thread(window);
        Thread thread2 = new Thread(window);
        Thread thread3 = new Thread(window);
        
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");
        
        thread1.start();
        thread2.start();
        thread3.start();
        
        }
    }

class window implements Runnable{
    
    int tickets = 100;
    Object obj= new Object();
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            show();
            }
            
        }
    public synchronized void  show() {
        
        synchronized (obj) {
            if(tickets>0){
                System.out.println(Thread.currentThread().getName()+":卖出第"+tickets+"张票");
                tickets=tickets-1;
            }
        }
    }        
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值