zoukankan      html  css  js  c++  java
  • 多线程访问共享对象和数据的方式

    在多线程访问共享对象和数据时候大致可以分为两大类。

    1:如果每个线程执行的代码相同,可以使用同一个runnable对象,这个runnable对象中有那个共享对象。如:买票系统。

     1 public class MulteThreadlShareData {
     2     public static void main(String[] args) {
     3         ShareData shareData = new ShareData();
     4         new Thread(shareData).start();
     5         new Thread(shareData).start();
     6     }
     7     
     8     static class ShareData implements Runnable{
     9         int count = 100;
    10         @Override
    11         public void run() {
    12             while(count>0){
    13                 decrease();
    14             }
    15         }
    16         public synchronized void decrease(){
    17             count--;
    18             System.out.println(Thread.currentThread().getName()+"this count: "+count);
    19         }
    20         
    21     }
    22 }

    2:如果每个线程执行的代码不相同,就要用不同的runnable对象了。这种方式又有两种来实现这些runnable对象之间的数据共享。

    •   将共享数据封装在另一个对象中,然后将这个对象逐一传递给各个runnable对象中。每个线程共享数据的操作方法也分配到了这个对象身上去完成,这样容易实现针对该数据进行共享数据的互斥和通信。代码实现如下:
       1 public class MulteThreadlShareData2 {
       2     public static void main(String[] args) {
       3         final ShareData shareData = new ShareData();
       4         new Thread(new Decrease(shareData)).start();
       5         new Thread(new Increment(shareData)).start();
       6     }
       7     
       8     static class Decrease implements Runnable{
       9         private ShareData shareData;
      10         public Decrease(ShareData shareData){
      11             this.shareData=shareData;
      12         }
      13         @Override
      14         public void run() {
      15             shareData.decrease();
      16         }
      17         
      18     }
      19     static class Increment implements Runnable{
      20         private ShareData shareData;
      21         public Increment(ShareData shareData){
      22             this.shareData=shareData;
      23         }
      24         @Override
      25         public void run() {
      26             shareData.increment();
      27         }
      28         
      29     }
      30     
      31     static class ShareData{
      32         int count = 100;
      33         public synchronized void decrease(){
      34             count--;
      35             System.out.println(Thread.currentThread().getName()+"decrease this count: "+count);
      36         }
      37         public synchronized void increment(){
      38             count++;
      39             System.out.println(Thread.currentThread().getName()+"increment this count: "+count);
      40         }
      41     }
      42 }
    •   将这些runnable对象作为某个类的内部类,共享数据作为这个外部类的成员变量,每个线程对共享数据的操作也分配到外部类,以便实现对共享数据进行的各个操作进行互斥和通信,作为内部类的各个runnable对象调用外部类的这些方法。
       1 public class MulteThreadlShareData3 {
       2     static int count = 100;
       3     public static void main(String[] args) {
       4         new Thread(new Decrease()).start();
       5         new Thread(new Increment()).start();
       6         
       7     }
       8     public synchronized static void decrease(){
       9         count--;
      10         System.out.println(Thread.currentThread().getName()+"decrease this count: "+count);
      11     }
      12     public synchronized static void increment(){
      13         count++;
      14         System.out.println(Thread.currentThread().getName()+"increment this count: "+count);
      15     }
      16     static class Decrease implements Runnable{
      17         @Override
      18         public void run() {
      19             decrease();
      20         }
      21         
      22     }
      23     static class Increment implements Runnable{
      24         @Override
      25         public void run() {
      26             increment();
      27         }
      28         
      29     }
      30 }
    •   上面两种方式的结合:将共享数据封装到另一个对象中,各个线程对共享数据操作的方法也分配到那个对象上去完成,对象作为外部类的成员变量或方法的局部变量,每个runnable对象作为外部类中的成员内部类或局部内部类。
       1 public class MulteThreadlShareData1 {
       2     public static void main(String[] args) {
       3         final ShareData shareData = new ShareData();
       4         new Thread(new Runnable() {
       5             @Override
       6             public void run() {
       7                 while(true){
       8                     shareData.decrease();
       9                 }    
      10             }
      11         }).start();
      12         new Thread(new Runnable() {
      13             @Override
      14             public void run() {
      15                 while(true){
      16                     shareData.increment();
      17                 }
      18                 
      19             }
      20         }).start();
      21     }
      22     
      23     static class ShareData{
      24         int count = 100;
      25         public synchronized void decrease(){
      26             count--;
      27             System.out.println(Thread.currentThread().getName()+"this count: "+count);
      28         }
      29         public synchronized void increment(){
      30             count++;
      31             System.out.println(Thread.currentThread().getName()+"this count: "+count);
      32         }
      33     }
      34 }

    总之:要同步和互斥的几段代码最好放在几个独立的方法中,这些方法在放在同一个类中,这样容易实现他们之间的同步互斥和通信。

  • 相关阅读:
    java操作生成jar包 和写入jar包
    jboss配置jndi连接池
    windows 域的LDAP查询相关举例
    LDAP error Code 及解决方法
    HDU 6417
    CF1299D Around the World
    codechef Chef and The Colored Grid
    Educational Codeforces Round 82 (Rated for Div. 2)
    CF1237F Balanced Domino Placements
    CF1254E Send Tree to Charlie
  • 原文地址:https://www.cnblogs.com/lcngu/p/5150024.html
Copyright © 2011-2022 走看看