0002-多线程线程安全

Synchronized  

1.同步函数用的锁是this

  

package cn.yorz.testthread;
/**
 * 
 * @author Administrator
 *	验证同步函数用的this
 *		
 */
class Ticket implements Runnable
{
	private int tick = 100;
	Object obj = new Object();
	boolean flag = true;
	public void run(){
		if(flag){
			while(true)
				synchronized(this){
					//注意这里的锁要一致
					 //跟show()函数一样都是一个锁,show()锁是本身所以是this
			       //同步的前提是:1、两个及其以上的线程;2、锁一样
					if(tick>0){
						try{Thread.sleep(10);}catch(Exception e){}
						System.out.println(Thread.currentThread().getName()+"同步代码块"+tick--);
					}
				}
		}else{
			while(true)
				show();
		}
	}
	public synchronized void show(){	//锁是this
		
		if(tick>0){
			try{Thread.sleep(10);}catch(Exception e){}
			System.out.println(Thread.currentThread().getName()+"同步函数...."+tick--);
		}
	}
}    
public  class TestSynchronizedFunction{
	public static void main(String[] args){
		//验证数据并没有冲突 于是用的就是this锁
		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();
	}
}

2,静态方法用的锁是class对象

 

 

 多线程死锁问题

 

package cn.yorz.testthread;
/**
 * 
 * @author Administrator
 * 多线程死锁问题,多个锁对象才能产生死锁现象
*/ public class DeadLock implements Runnable{ private int flag = 1; private Object obj1 = new Object(), obj2 = new Object(); public void run() { System.out.println(Thread.currentThread().getName()+":flag=" + flag); if (flag == 1) { synchronized (obj1) { System.out.println("1:"+Thread.currentThread().getName()+"我已经锁定obj1,休息0.5秒后锁定obj2去!"); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (obj2) { System.out.println(Thread.currentThread().getName()+":1"); } } } if (flag == 0) { synchronized (obj2) { System.out.println("0:"+Thread.currentThread().getName()+"我已经锁定obj2,休息0.5秒后锁定obj1去!"); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (obj1) { System.out.println(Thread.currentThread().getName()+":0"); } } } } public static void main(String[] args) { DeadLock deadLock = new DeadLock(); Thread thread01 = new Thread(deadLock); Thread thread02 = new Thread(deadLock); System.out.println("线程开始喽!"); thread01.start(); thread02.start(); try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } deadLock.flag=0; } }

 

 

java内存模型

  1.多线程的三大特性

    原子性

    有效性

    可见性 

  2.java内存模型和java内存结构

    java内存模型:jmm,与线程的可见性相关。

    java内存结构:jvm,堆和栈

 

java内存模型详解

 

JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。

 

 Volatile关键字

  作用:保证线程之间可见,但不保证原子性。既:一个线程修改了一个共享变量的值可以立马通知给另一个线程。

package cn.yorz.testthread;
/**
 * 
 * @author Administrator
 * 测试volatile关键字
 */
//线程
class VolatileThread extends Thread{
    private volatile boolean flag=true;  //如果没有volatile关键字,此段程序有无法终止的可能
    
    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"线程开始执行");    
        while(flag) {
            
        }
        
        System.out.println(Thread.currentThread().getName()+"线程执行结束");    
    }
}


public class TestVolatile {
    public static void main(String[] args) {
        VolatileThread t1=new VolatileThread();
        t1.start();
        
  
    //此段代码注释掉可以执行结束,不注释掉要加volatile修饰flag,否则无法停止
try { Thread.sleep(3000); t1.setFlag(false); System.out.println(Thread.currentThread().getName()+"已经修改flag的值"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }
System.out.println(t1.getName()
+"flag的值"+t1.isFlag()); } }

 atomicinteger原子类

 

public class TestVolatileNotAtomic extends Thread{
    private volatile static  int count=0;
    private  static  AtomicInteger atomicInteger=new AtomicInteger(0); //原子类       
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            count++;
            atomicInteger.incrementAndGet();//自增
        }
        System.out.println(Thread.currentThread().getName()+"count---"+count);
        System.out.println(Thread.currentThread().getName()+"atomicInteger---"+atomicInteger.get());  //得到结果
    }
    
    
    public static void main(String[] args) {
        //创建十个线程
        TestVolatileNotAtomic[] testVolatileNotAtomics=new TestVolatileNotAtomic[10];
        for (int i = 0; i < testVolatileNotAtomics.length; i++) {
            testVolatileNotAtomics[i]=new TestVolatileNotAtomic();
        }
        //遍历start
        for (int i = 0; i < testVolatileNotAtomics.length; i++) {
            
            testVolatileNotAtomics[i].start();
        }
    }
}

 

转载于:https://www.cnblogs.com/xiayuer0114/p/9842529.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值