জ্যাকএক্সবি প্রসঙ্গ তৈরি করে এবং মার্শালারগুলি ব্যয় করে


120

প্রশ্নটি কিছুটা তাত্ত্বিক, জ্যাকএক্সবি প্রসঙ্গ তৈরির জন্য মার্শালার এবং আনমারশ্লার কী খরচ হবে?

আমি খুঁজে পেয়েছি যে আমার কোডটি প্রতিটি মার্শালিংয়ের প্রসঙ্গে এবং মার্শালার তৈরির পরিবর্তে একই জ্যাকএক্সবি প্রসঙ্গ এবং সম্ভবত সমস্ত মার্শালিং ক্রিয়াকলাপের জন্য একই মার্শালার রেখে উপকৃত হতে পারে।

তাহলে জএএক্সবি প্রসঙ্গে এবং মার্শালার / আনমারশালার তৈরি করতে কী খরচ হবে? প্রতিটি মার্শালিং অপারেশনের জন্য প্রসঙ্গ + মার্শালার তৈরি করা কি ঠিক আছে বা এড়ানো ভাল?

উত্তর:


244

দ্রষ্টব্য: আমি EclipseLink JAXB (MOXy) নেতৃত্ব এবং জ্যাকএক্সবি 2 (জেএসআর -২২২ ) বিশেষজ্ঞ দলের সদস্য।

JAXBContextথ্রেডটি নিরাপদ এবং কেবল একবার তৈরি করা উচিত এবং একাধিকবার মেটাডেটা শুরু করার ব্যয় এড়াতে পুনরায় ব্যবহার করা উচিত। Marshallerএবং Unmarshallerথ্রেড নিরাপদ নয়, তবে এটি তৈরির জন্য হালকা ওজন এবং প্রতি ক্রিয়াকলাপে তৈরি করা যেতে পারে।


7
দুর্দান্ত উত্তর জ্যাকসবির নেতৃত্ব হিসাবে আপনার অভিজ্ঞতার ভিত্তিতে আমি এখন আত্মবিশ্বাসী হতে পারি।
ভ্লাদিমির

7
আমি আপনাকে বিশ্বাস করি, তবে এটি কি ডকুমেন্টেশনের কোথাও পাওয়া যাবে?
হুরদা

3
এটি আরআই এর জন্য নথিভুক্ত করা হয়েছে: jaxb.java.net/guide/Performance_and_thread_safety.html (তবে ম্যাক্সি এএফআইএইকে নয়)
কয়েলেট

39
জাভাডোক এ দয়া করে নির্দিষ্ট করুন। এই গুরুত্বপূর্ণ দিকগুলি অনির্ধারিত হওয়া সন্তোষজনক নয়।
টমাস ডাব্লু

6
জাভাডোকের মধ্যে এটি উল্লেখ করা হয়নি যে জ্যাকএক্সবিএনটেক্সট থ্রেড নিরাপদ। এবং কীভাবে জ্যাকএক্সবি ব্যবহার করবেন তার প্রতিটি উদাহরণ, এটি একবার তৈরি করা উচিত এবং থ্রেডে ভাগ করা উচিত তা উল্লেখ করতে ব্যর্থ। ফলস্বরূপ আমি এখন একটি লাইভ সিস্টেম থেকে আরও একটি হোলিং সম্পদ ফাঁস অপসারণ করছি। Grrrrrrr।
রেগ হুইটন

42

মূলত, আপনি একটি একক থাকা উচিত JAXBContextএবং স্থানীয় দৃষ্টান্ত Marshallerএবং Unmarshaller

JAXBContextদৃষ্টান্ত থ্রেড-নিরাপদ সময় হয় Marshallerএবং Unmarshallerদৃষ্টান্ত হয় না সুতা-নিরাপদ ও থ্রেড জুড়ে কখনো ভাগ করা উচিত।


উত্তর করার জন্য ধন্যবাদ. দুর্ভাগ্যক্রমে আমাকে কেবল একটি উত্তর নির্বাচন করতে হবে :-)
ভ্লাদিমির

15

এটি অত্যন্ত দুঃখের বিষয় যা জাভাডোকে এটি নির্দিষ্টভাবে বর্ণিত নয়। আমি যা বলতে পারি তা হ'ল স্প্রিং একটি গ্লোবাল জ্যাকএক্সবিএনটেক্সট ব্যবহার করে, যা থ্রেডগুলির মধ্যে ভাগ করা হয়, যেখানে এটি প্রতিটি মার্শালিং অপারেশনের জন্য একটি নতুন মার্শালার তৈরি করে, কোডটিতে একটি জাভাদোক মন্তব্য দিয়ে বলেছে যে জ্যাকএক্সবি মার্শালাররা অগত্যা থ্রেড-নিরাপদ নয়।

: একই এই পৃষ্ঠাতে বলেন https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#other-miscellaneous-topics-performance-and-thread-safety

আমি অনুমান করব যে জ্যাকএক্সবিএনটেক্সট তৈরি করা একটি ব্যয়বহুল ক্রিয়াকলাপ, কারণ এতে টীকাগুলির জন্য স্ক্যানিং ক্লাস এবং প্যাকেজ অন্তর্ভুক্ত রয়েছে। তবে এটি পরিমাপ করা সবচেয়ে ভাল উপায়।


হাই @ জেবি, দুর্দান্ত উত্তর বিশেষত আপনার পরিমাপ সম্পর্কে মন্তব্য এবং কেন জ্যাকএক্সবিএনটেক্সট ব্যয়বহুল।
ভ্লাদিমির

1
জাভাডোক জীবনচক্রের গুরুত্বপূর্ণ তথ্যগুলিতে সর্বদা দুর্বল ছিল । এটি নিশ্চিতভাবে আমাদের সম্পত্তি প্রাপ্তি এবং সেটটারদের তুচ্ছ পুনরাবৃত্তি দেয়, তবে কীভাবে / কোথায় একটি উদাহরণ, মিউটেশন এবং থ্রেড-সুরক্ষা পাওয়া যায় তা জেনে রাখা .. এটি সবচেয়ে গুরুত্বপূর্ণ বিষয়গুলি পুরোপুরি মিস করেছে বলে মনে হয়। দীর্ঘশ্বাস :)
টমাস ডাব্লু

4

জ্যাকসবি ২.২ (জেএসআর -২২২ ) এর এই অংশটি "৪.২ জ্যাকএক্সবিএনটেক্সট" বিভাগে রয়েছে:

একটি JAXBContextউদাহরণ তৈরি করার সাথে জড়িত ওভারহেড এড়াতে , একটি জ্যাক্সবি অ্যাপ্লিকেশনকে জ্যাকএক্সবিএনটেক্সট উদাহরণটি পুনরায় ব্যবহার করতে উত্সাহ দেওয়া হচ্ছে । অ্যাবস্ট্র্যাক্ট ক্লাস জ্যাকএক্সবিএনটেক্সট একটি প্রয়োগকরণ থ্রেড-নিরাপদ হওয়া প্রয়োজন , সুতরাং, একটি অ্যাপ্লিকেশন একাধিক থ্রেড একই JAXBContext উদাহরণ ভাগ করে নিতে পারে share

[..]

জ্যাকএক্সবিএনটেক্সট ক্লাসটি অপরিবর্তনীয় এবং এইভাবে থ্রেডসেফের জন্য ডিজাইন করা হয়েছে। জ্যাকসবিন্টেক্সট-এর একটি নতুন উদাহরণ তৈরি করার সময় যে পরিমাণ গতিশীল প্রক্রিয়াকরণ হতে পারে তা প্রদত্ত, এটি প্রস্তাবিত হয় যে কোনও জ্যাকসবিএনটেক্সট উদাহরণটি থ্রেডে ভাগ করা উচিত এবং অ্যাপ্লিকেশন কর্মক্ষমতা উন্নত করতে যতটা সম্ভব পুনরায় ব্যবহার করা উচিত।

দুর্ভাগ্যক্রমে, স্পেসিফিকেশন থ্রেড-সুরক্ষা Unmarshallerএবং সম্পর্কিত কোনও দাবি করে নাMarshaller । সুতরাং এটি অনুমান করা ভাল যে তারা তা নয়।


3

আমি এই সমস্যাটি ব্যবহার করে সমাধান করেছি:

  • ভাগ করা থ্রেড নিরাপদ JAXBContext এবং থ্রেড স্থানীয় আন / মার্শালারদের
  • (সুতরাং তাত্ত্বিকভাবে, অনেক অন ​​/ মার্শালার থাকবে থ্রেডগুলি অ্যাক্সেস করেছে সেগুলি উদাহরণ রয়েছে)
  • কেবল আন / মার্শালারের সূচনাতে সিঙ্ক্রোনাইজেশন সহ ।
public class MyClassConstructor {
    private final ThreadLocal<Unmarshaller> unmarshallerThreadLocal = new ThreadLocal<Unmarshaller>() {
        protected synchronized Unmarshaller initialValue() {
            try {
                return jaxbContext.createUnmarshaller();
            } catch (JAXBException e) {
                throw new IllegalStateException("Unable to create unmarshaller");
            }
        }
    };
    private final ThreadLocal<Marshaller> marshallerThreadLocal = new ThreadLocal<Marshaller>() {
        protected synchronized Marshaller initialValue() {
            try {
                return jaxbContext.createMarshaller();
            } catch (JAXBException e) {
                throw new IllegalStateException("Unable to create marshaller");
            }
        }
    };

    private final JAXBContext jaxbContext;

    private MyClassConstructor(){
        try {
            jaxbContext = JAXBContext.newInstance(Entity.class);
        } catch (JAXBException e) {
            throw new IllegalStateException("Unable to initialize");
        }
    }
}

8
থ্রেডলোকাল কোনও সুবিধা ছাড়াই অন্যান্য সাবলেট সমস্যাগুলি প্রবর্তন করবে। কেবলমাত্র একটি সিএএক্সবিবিসেক্সটেক্সট রাখুন (এটি ব্যয়বহুল অংশ) এবং যখনই প্রয়োজন হবে একটি নতুন আনমশালার তৈরি করুন।
ইয়ামাজোরস

2

আর ভালো!! উপরের পোস্ট থেকে ভাল সমাধানের ভিত্তিতে , কনস্ট্রাক্টরটিতে কেবল একবার প্রসঙ্গ তৈরি করুন এবং ক্লাসের পরিবর্তে এটি সংরক্ষণ করুন।

লাইনটি প্রতিস্থাপন করুন:

  private Class clazz;

এটার সাথে:

  private JAXBContext jc;

এবং এটির সাথে প্রধান নির্মাতা:

  private Jaxb(Class clazz)
  {
     this.jc = JAXBContext.newInstance(clazz);
  }

সুতরাং getMarshaller / getUnmarshaller এ আপনি এই লাইনটি সরাতে পারেন:

  JAXBContext jc = JAXBContext.newInstance(clazz);

এই উন্নতিটি আমার ক্ষেত্রে, প্রক্রিয়াকরণের সময়গুলি 60 60 70ms থেকে মাত্র 5 ~ 10ms এ নেমে আসে


আপনি যে পরিমাণ এক্সএমএল ফাইল পার্স করছেন তা কত বড়। আপনি কি খুব বড় এক্সএমএল ফাইলের সাথে উল্লেখযোগ্য উন্নতি দেখতে পাচ্ছেন?
জন

1
এটি আসলে বড় এক্সএমএল ফাইলের বিষয় নয় (খনিগুলি কেবল ২-৩ কেবি থেকে + 6 এমবি পর্যন্ত যায়), তবে এর পরিবর্তে খুব বেশি সংখ্যক এক্সএমএল ফাইলের বিষয়টি (আমরা এখানে প্রতি মিনিটে 10,000 এক্সএমএল অনুরোধের কথা বলছি); সেক্ষেত্রে একবারে এই ছোট্ট এমএস অর্জনের জন্য প্রসঙ্গ তৈরি করা একটি বিশাল পার্থক্য করে
tbarderas

1

আমি সাধারণত ThreadLocalক্লাসের ধরণ দিয়ে এ জাতীয় সমস্যাগুলি সমাধান করি । প্রতিটি ক্লাসের জন্য আপনার আলাদা মার্শালার দরকার রয়েছে তা প্রমাণ করে আপনি এটিকে একটি- singletonম্যাপ প্যাটার্নের সাথে একত্রিত করতে পারেন ।

কাজের জন্য আপনাকে 15 মিনিট বাঁচাতে। এখানে আমার Jaxb মার্শালার্স এবং আনমারশালারদের জন্য থ্রেড-সেফ কারখানার বাস্তবায়ন অনুসরণ করা হয়েছে।

এটি আপনাকে নীচে উদাহরণগুলি অ্যাক্সেস করার অনুমতি দেয় ...

Marshaller m = Jaxb.get(SomeClass.class).getMarshaller();
Unmarshaller um = Jaxb.get(SomeClass.class).getUnmarshaller();

এবং আপনার যে কোডটির প্রয়োজন হবে সেটি হল একটি সামান্য জ্যাক্সবি ক্লাস যা নীচের মত দেখাচ্ছে:

public class Jaxb
{
  // singleton pattern: one instance per class.
  private static Map<Class,Jaxb> singletonMap = new HashMap<>();
  private Class clazz;

  // thread-local pattern: one marshaller/unmarshaller instance per thread
  private ThreadLocal<Marshaller> marshallerThreadLocal = new ThreadLocal<>();
  private ThreadLocal<Unmarshaller> unmarshallerThreadLocal = new ThreadLocal<>();

  // The static singleton getter needs to be thread-safe too, 
  // so this method is marked as synchronized.
  public static synchronized Jaxb get(Class clazz)
  {
    Jaxb jaxb =  singletonMap.get(clazz);
    if (jaxb == null)
    {
      jaxb = new Jaxb(clazz);
      singletonMap.put(clazz, jaxb);
    }
    return jaxb;
  }

  // the constructor needs to be private, 
  // because all instances need to be created with the get method.
  private Jaxb(Class clazz)
  {
     this.clazz = clazz;
  }

  /**
   * Gets/Creates a marshaller (thread-safe)
   * @throws JAXBException
   */
  public Marshaller getMarshaller() throws JAXBException
  {
    Marshaller m = marshallerThreadLocal.get();
    if (m == null)
    {
      JAXBContext jc = JAXBContext.newInstance(clazz);
      m = jc.createMarshaller();
      marshallerThreadLocal.set(m);
    }
    return m;
  }

  /**
   * Gets/Creates an unmarshaller (thread-safe)
   * @throws JAXBException
   */
  public Unmarshaller getUnmarshaller() throws JAXBException
  {
    Unmarshaller um = unmarshallerThreadLocal.get();
    if (um == null)
    {
      JAXBContext jc = JAXBContext.newInstance(clazz);
      um = jc.createUnmarshaller();
      unmarshallerThreadLocal.set(um);
    }
    return um;
  }
}

10
থ্রেডলোকাল কোনও সুবিধা ছাড়াই অন্যান্য সাবলেট সমস্যাগুলি প্রবর্তন করবে। কেবলমাত্র একটি সিএএক্সবিবিসেক্সটেক্সট রাখুন (এটি ব্যয়বহুল অংশ) এবং যখনই প্রয়োজন হবে একটি নতুন আনমশালার তৈরি করুন।
ইয়ামাজোরস

আপনি একাধিক ক্লাসে পাস করতে পারার কারণে আপনার আসলে আলাদা জ্যাকএক্সবিএনটেক্সটসের দরকার নেই। সুতরাং, আপনি যদি অনুমান করতে পারেন কোন ক্লাস মার্শাল হতে চলেছে, আপনি একটি একক ভাগ করা একটি তৈরি করতে পারেন। এছাড়াও, জ্যাকএক্সবি স্পেকগুলির জন্য তাদের ইতিমধ্যে থ্রেডসেফ করা দরকার।
মৌগানরা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.