博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于线程的进一步介绍
阅读量:5132 次
发布时间:2019-06-13

本文共 2279 字,大约阅读时间需要 7 分钟。

             之前对线程进行过简单介绍,现在更进一步介绍一下。

              在创建线程使用第二种方法,即给Thread()类传入一个实现了Runnable接口的对象时,可能创建的两个线程用的是同一个对象,就存在共享资源。两个线程同时对其进行操作,而且顺序不定,存在安全问题。例:

class Resource implements Runnable {

 public int i;                                                             
 public  Resource(int _i){
  i = _i;
 }
 public void run(){
  while(true){
   if (i>0){
    i--;
    System.out.println(Thread.currentThread().getName()+"   "+i);
   }
          else
    break;
  }
 }
}
public class TestThread{
 public static void main(String[] args){
  Resource m = new Resource(100);
  Thread t1 = new Thread(m);
  Thread t2 = new Thread(m);
  t1.start();
  t2.start();
 }
}

 

                在这个例子中,线程t1和t2同时访问m的资源,都执行m对应对象的run()方法,即对i进行自减。但是两个线程的执行顺序不能确定,因此执行的结果不能确定,可能同时会进行对i的操作,安全性存在很大问题。举个形象的例子,一对夫妇,账户里有1000元,他们各自为这个账户办理了一张银行卡,相约一起取钱,两人同时按下取钱的按钮,如果线程不安全则两人会取走2000元,显然这是不合理的。

                解决线程安全问题,java引入了监视器(monitor)来保证共享数据操作的同步性,任何对象都可以作为一个监视器,关键字synchronized修饰某个对象后,该对象就成为监视器。synchronized最常用的是以下两种方法:1.synchronized代码块:监视器就是指定的对象;2.synchronized方法:监视器就是this对象。

例:代码块方法:

class Resource implements Runnable {

 volatile public int i;       
 volatile public Integer it;
 public  Resource(int _i){
  i = _i;
  it = new Integer(i);
 }
 public  void run(){  
  while(true){   
   synchronized(it){
     if (i>0)
     {
    try{
    Thread.sleep(200);   
    }
    catch(Exception e){}
    i--;
    System.out.println(Thread.currentThread().getName()+"  "+i);
     }
     else{
    System.out.println(Thread.currentThread().getName());
    break;
     }
   }
  }
 }
}
public class TestSecurity{
 public static void main(String[] args){
  Resource m = new Resource(100);
  Thread t1 = new Thread(m);
  Thread t2 = new Thread(m);    
  t1.start();    
  t2.start();  
 }
}

             具体不同就是标红的地方,给Resourse类新增加了一个Integer类的对象it,然后对其初始化,在run()方法中用synchronized方法块将if判断语句等包起来,监视器是it对象,也就是m对应的对象。在一个线程抢到执行权之后,只有这个线程执行完方法快包围的语句之后才能两个线程重新抢锁即执行权。

例:方法:

class Resource implements Runnable {

 volatile public int i;         
 public  Resource(int _i){
  i = _i;
 }
 public synchronized void run(){  
  while(true){      
   if (i>0)
   {
     try{
     Thread.sleep(200);   
     }
     catch(Exception e){}
    i--;
    System.out.println(Thread.currentThread().getName()+"  "+i);
     }
   else{
    System.out.println(Thread.currentThread().getName());
    break;
   }
   
  }
 }
}
public class TestSecurity{
 public static void main(String[] args){
  Resource m = new Resource(100);
  Thread t1 = new Thread(m);
  Thread t2 = new Thread(m);    
  t1.start();    
  t2.start();  
 }
}

         方法为标红部分,监视器的对象是this即当前对象m。线程的执行情况同第一种,也是先抢锁,抢到的线程执行方法里的内容,只有将方法全部执行完,两个线程开始重新抢锁。

转载于:https://www.cnblogs.com/Wangjiaq/p/8799302.html

你可能感兴趣的文章
homework-06
查看>>
POJ 2584 T-Shirt Gumbo 构图 最大流
查看>>
HDU 1712 ACboy needs your help(简单分组DP)
查看>>
PHP学习随笔(3):数组
查看>>
Java知多少(9) import及Java类的搜索路径
查看>>
三大主流软件负载均衡器对比(LVS VS Nginx VS Haproxy)
查看>>
SQL Server 2008 R2 中英文 开发版/企业版/标准版 链接地址
查看>>
android: ListView设置emptyView 误区
查看>>
android framework-下载Android系统源代码
查看>>
php array_merge和“+”的区别和使用《细说php2》
查看>>
Spark Streaming ReceiverTracker架构设计
查看>>
简单正则验证
查看>>
kickstart注意事项
查看>>
只有程序员能看懂的十个笑话 2014-08-05 16:07 54人阅读 评论(0) 收藏...
查看>>
linux 下执行.sh文件总是提示permission denied
查看>>
CentOS7使用firewalld打开关闭防火墙与端口
查看>>
在装有windows跟ubuntu的机器上重新安装windows后修复ubuntu的grub
查看>>
keys
查看>>
HTML小知识点
查看>>
css 选择器
查看>>