java 数据共享与线程状态

1.java数据共享

线程创建方式

extend Thread ,启动时直接 对象调用start方法 

public class MultiThread extends Thread{
	@Override
	public void run() {
		while(true) {
			System.out.println("111");	
		}
	}
	public static void main(String[] args) {
		new MultiThread().start();
	}
}

implements Runable接口 ,启动时要新建Thread,把实现接口对象带入 Thread中,然后启动。

public class MultiThread implements Runnable{

	@Override
	public void run() {
		while(true) {
			System.out.println("111");	
		}
	}
	public static void main(String[] args) {
		MultiThread thread = new MultiThread();
		//把runable对象带入Thread中启动
		new Thread(thread,"thread1").start();;
	}
}

java数据共享分析

 例子引用自 https://blog.csdn.net/kong_gu_you_lan/article/details/57083185

 对于例子中线程同步1的银行取钱问题,其调用过程如下,最终出现了 两个人短间隔各自取钱2000,取完后各自打印的余额结果却都是3000

public class ThreadTest {

    public static void main(String[] args) {
        // 创建一个账户,里面有存款5000元
        Account account = new Account(5000);
        // 模拟取钱过程
        GetMoney getMoney = new GetMoney(account);
        new Thread(getMoney, "你").start();
        new Thread(getMoney, "你老婆").start();
    }
}

因为两个线程传入了同一个对象getmoney,(Thread可见的代码并不是就是线程本身,Thread只是调用线程的API).对于这个例子,相当于传递给两个线程getmoney对象(内存地址的引用)进行处理,我获得getmoney时count值为5000,由于延时原因,此时妻子的线程也已经启动,此时妻子从内存获取的count值仍是5000,仍没有被修改,随后各自执行run方法,就各自显示了3000元余额。 

共享数据解决方案synchronized

1.可以通过synchronized锁机制 synchronized(object)对资源上锁,保证同时只有object对象可以拥有共享资源。

synchronized可以修饰方法,代码块,和某一变量

public synchronizedvoid get(); 对方法上锁,等同于在方法内部添加代码块  public void get(){ sychronized(this){ //代码块} }

synchronized(this){ //代码块} 对一段代码上锁

synchronized(str1){  //处理逻辑 } 对变量str1上锁 ,上锁范围仅为{ }内的str1对象。

死锁的避免

 当 两个进程 共享a,b变量,且要满足同时拥有才能完成操作,当出现各自拥有a,b,不释放a,b等待对方释放b,a的时候,就出现死锁。

public class MultiThread implements Runnable{
	Integer a, b;
	public MultiThread(int a, int b) {
		this.a=a;
		this.b=b;
	}
	@Override
	public void run(){
		try {
			System.out.println("a+b的结果是  :"+count());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public int count() throws InterruptedException {
		//必须把b写道a内部,才能保证同时拥有a,b才能完成操作。 不然存在资源被释放,不符合死锁条件。
		synchronized(a){
			System.out.println("a已被线程"+Thread.currentThread().getName()+"锁定");
			Thread.sleep(100);
			synchronized(b){
				System.out.println("b已被线程"+Thread.currentThread().getName()+"锁定");
			}
		}
		
		return a+b;
	}
	public static void main(String[] args) {
		Integer a =40 , b = 60;
		MultiThread thread1 = new MultiThread(a,b);
		MultiThread thread2 = new MultiThread(b,a);
		//把runnable对象带入Thread中启动
		new Thread(thread1,"thread1").start();
		new Thread(thread2,"thread2").start();;
	}
}

执行结果

                                                        a已被线程thread1锁定
                                                        a已被线程thread2锁定

程序源码地址 :https://download.csdn.net/download/mychinasty/10925349

总结

1. 当出现资源共享,在设置锁的时候,要避免出现死锁

2. 本质讲,Thread是一个启动的载体,是线程操作的API, 其可控内容为 Thread创建的对象或者实现Runable接口的对象。启动多个Thread对同一个对象进行处理时,本质上多个线程都拥有该对象在内存中的内容。(对象的内存copy)。所以当多个Thread(对象,name);操作对象为同一个时,就会出现多个线程共享同一个对象的资源,资源共享。

3. sysnchronized(obj) 本质作用为obj对象在代码段,数据段,堆栈段的内容   (obj对象,可能是程序段,或者数据)

2.java线程状态

线程状态分类

新建状态:new Thread, 只是一个API的壳子,并未执行任何操作。

就绪状态:已获得除CPU之外的全部其他资源,在就绪队列中等待cpu。

阻塞状态:未获得运行所需资源而等待的状态,当获得完整之后,回插入就绪队列。

运行状态:线程正在执行的状态。当出现cpu时间片到期,会转变为就绪状态;运行期间缺少资源时,会转变为阻塞状态。

java中的线程状态

 博客园的文章介绍的很好,链接如下 https://www.cnblogs.com/happy-coder/p/6587092.html

对于开发而言,线程的阻塞与唤醒 需要着重了解 ,归纳如下:

同步阻塞synchronized: 正在运行的线程未获得同步锁时,进入阻塞状态,不会释放自身已锁定的资源,当获得其余线程释放的同步锁以及其余资源时,转变为就绪状态。

wait()阻塞:线程主动阻塞,会释放自身的同步锁。需要主动唤醒才能解除wait()状态(notify()和notifyAll() Thread.interrupt() 
等待时间过完),唤醒后一般仍未阻塞状态,需要等待重新获得同步锁及其他资源后,进入就绪状态。

sleep()阻塞:线程休眠,不放弃自身所持有的同步锁。超时后进入就绪状态。

join()阻塞:在执行线程中,调用其余线程的jion()方法。thread2.jion(),会等待thread2执行完后在执行当前线程,此时状态与sleep()类似。

yield()阻塞:线程从运行状态切换到阻塞状态,不释放本身同步锁。

interrupt()

待补充 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值