থাড.স্টার্ট () এর পরিবর্তে আপনি কখন জাওয়ার থ্রেড.আরুন () কল করবেন?


109

আপনি যখন জাভা এর thread.run()পরিবর্তে কল করবেন thread.start()?


47
আমি যখন থ্রেড.স্টার্ট () পদ্ধতি? :)
বিল

3
@ ব্ল্যাঙ্ক, উত্তরটি সহজ: t.run()আপনি যখন tবর্তমান থ্রেডের কাজটি t.start()চালাতে চান এবং যখন আপনি নিজেই tথ্রেডে টাস্কটি চালাতে চান t। বা আপনি প্রকৃত ব্যবহারের ক্ষেত্রে জিজ্ঞাসা করছেন?
পেসারিয়ার

2
আপনি যখন একজন নির্বোধ এবং এক ঘন্টা ডিবাগিং মাল্ট্রিথ্রেড কোড ব্যয় করতে চান ঠিক তখনই বুঝতে পারেন যে আপনার কেবলই ডাক দেওয়া উচিত ছিল start()! আমার মতো ... এই পদ্ধতিটি জনসাধারণের উচিত নয়!
পিয়েরে হেনরি

উত্তর:


113

আপনি কোনও নির্দিষ্ট ইউনিট পরীক্ষায় রান () কে কল করতে চাইতে পারেন যা কার্যকরীতার সাথে কঠোরভাবে জড়িত, একযোগের সাথে নয়।


95

কখনও। কলিং রান () সরাসরি একটি সাধারণ পদ্ধতি কলের মতোই কেবল কোডটিকে সিঙ্ক্রোনসিভ করে (একই থ্রেডে) চালায়।


25
"কখনই" কিছুটা নিরঙ্কুশ। সম্ভবত সর্বদা একটি নতুন থ্রেড চান না, এবং এখনও কোডটি কার্যকর করুন?
তোমালাক

4
হতে পারে, তবে সেক্ষেত্রে কেবল রান () পদ্ধতি কল করার জন্য একটি নতুন থ্রেড তৈরি করা অযথা অপ্রয়োজনীয়। একটি রান্নেবল ইমপ্লীল তৈরি করা এবং হয় যে ইন-থ্রেডটি চালান বা এটি দিয়ে একটি নতুন থ্রেড শুরু করুন।
স্কট বেল

1
শুধু পুনর্বিবেচনা ... যদি না হয় তবে পদ্ধতিটি কেন প্রকাশ্য?
ফাঁকা

4
এটি সর্বজনীন কারণ থ্রেড চলমানযোগ্য প্রয়োগ করে। আপনি থ্রেড এবং ওভাররাইড রান () কে সাবক্লাস করতে পারেন, যা আপনার কোডটি রান্নেবলের মধ্যে রাখার মতো এবং থ্রেড কনস্ট্রাক্টরে পাস করার মতোই প্রভাব ফেলে। পৃথক রান্নেবল অবজেক্ট ব্যবহার করা আরও ভাল অনুশীলন, যদিও এটি আপনাকে আরও নমনীয়তা ছেড়ে দেয় (যেমন এটি কোনও নির্বাহকের কাছে প্রেরণ করা ইত্যাদি)।
অ্যাডাম ক্রুম

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

27

কোড স্টাইল জাভা থ্রেডগুলি প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী ফর্মটি নিয়েছে :

প্রশ্ন: থ্রেডের শুরু () এবং রান () পদ্ধতির মধ্যে পার্থক্য কী?

উত্তর: থ্রেড ক্লাসে পৃথক শুরু () এবং রান () পদ্ধতি থ্রেডেড প্রোগ্রামগুলি তৈরি করার দুটি উপায় সরবরাহ করে। শুরু () পদ্ধতিটি নতুন থ্রেডের সম্পাদন শুরু করে এবং রান () পদ্ধতিটি কল করে। শুরু () পদ্ধতিটি তত্ক্ষণাত্ ফিরে আসে এবং রান () পদ্ধতিটি ফিরে না আসা পর্যন্ত নতুন থ্রেডটি সাধারণত চলতে থাকে।

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

আপনার থ্রেডেড প্রোগ্রামের প্রকৃতির উপর নির্ভর করে থ্রেড রান () পদ্ধতিটি সরাসরি কল করা স্টার্ট () পদ্ধতির মাধ্যমে কল করার অনুরূপ আউটপুট দিতে পারে, তবে পরবর্তী ক্ষেত্রে কোডটি আসলে একটি নতুন থ্রেডে কার্যকর করা হয়।


thread's run() method executes the run() method of the Runnable object in the new thread instead.এটি সত্য নয় (বা কমপক্ষে আমার জাভা 8 উত্স কোড অন্যথায় বলে), তবে দুর্ভাগ্যক্রমে লিঙ্কটি ভাঙা বলে মনে হচ্ছে পরিবর্তে আমি এখানে ভুলটি রিপোর্ট করছি।
kajacx

1
@ তোমালাক, এটি জিজ্ঞাসা করা প্রশ্নের উত্তর দেয় না। প্রশ্নটি পার্থক্যের জন্য জিজ্ঞাসা করছে না, তবে ব্যবহারের ক্ষেত্রে জিজ্ঞাসা করছে যার thread.run()পরিবর্তে আমরা কল করব thread.start()
পেসারিয়ার

24

কার্যকর করা thread.run()কোনও নতুন তৈরি করে না Threadযাতে আপনার কোডটি কার্যকর করা হয়। এটি কেবলমাত্র বর্তমান থ্রেডে thread.run()কোডটি কার্যকর করে যা থেকে কোডটি চাওয়া হয়েছে ।

এক্সিকিউটিং thread.start()একটি নতুন ওএস স্তরের থ্রেড তৈরি করে যেখানে run()পদ্ধতিটি কল হয়।

সংক্ষেপে:

একক থ্রেডেড প্রোগ্রামিং → সরাসরি run()পদ্ধতিতে কল করা

মাল্টি থ্রেডেড প্রোগ্রামিং → start()পদ্ধতিটি কল করা

তদ্ব্যতীত, অন্যরা যেমন বলেছে, 'টেস্টিং' একমাত্র যুক্তিযুক্ত বিষয় বলে মনে হচ্ছে যেখানে আপনি run()সরাসরি আপনার কোড থেকে আবেদন করতে পারেন ।


13

এটি ইতিমধ্যে ইঙ্গিত করা হয়েছে, তবে কেবল স্পষ্ট করে বলা যায়: কেবলমাত্র এটি চালানো () পদ্ধতি বলার জন্য একটি নতুন থ্রেড অবজেক্ট তৈরি করা অযথা ব্যয়বহুল এবং এটি একটি প্রধান লাল পতাকা হওয়া উচিত। রান্নেবল ইমপ্ল তৈরি করার জন্য এটি একটি আরও ভাল, আরও ডিকোপলড ডিজাইন হবে এবং হয় (ক) পছন্দসই আচরণটি হলে সরাসরি এটি রান করুন () পদ্ধতিটি কল করুন , বা (খ) সেই রান্নেবলের সাথে একটি নতুন থ্রেড তৈরি করুন এবং থ্রেড শুরু করুন।

আরও ভাল, আরও decoupling জন্য, ইন্টারন্যাশনাল Executorএবং JDK 5 এবং আরও নতুন কাঠামো দেখুন। এটি আপনাকে সংক্ষেপে, কীভাবে কার্যকর করা হবে (এক্সিকিউটার বাস্তবায়ন, যা বর্তমান থ্রেডে রান্নেবল কার্যকর করতে পারে, একটি নতুন থ্রেডে, একটি পুল থেকে বিদ্যমান থ্রেডটি ব্যবহার করে ) কীভাবে কার্যকর করা হবে তা থেকে ডিকুয়াল করার সুযোগ দেয়, এবং কি না).


9

কল করুন thread.start(), এটি ঘুরে ফিরে আসবে thread.run()। আপনি কখন বাইপাস করে thread.start()সরাসরি যেতে চান এমন কোনও কেস ভাবতে পারে নাthread.run()


3
পরীক্ষার সময় একমাত্র বৈধ মামলা আমি ভাবতে পারি। অন্যথায়, রান () এর সামগ্রীগুলি পৃথক পদ্ধতিতে হওয়া উচিত যা রান দ্বারা বা অন্য কোনও উপায়ে কল হয় called
বিল করুন

9

থ্রেড ক্লাসে পৃথক start()এবং run()পদ্ধতিগুলি থ্রেডেড প্রোগ্রামগুলি তৈরি করার দুটি উপায় সরবরাহ করে। start()পদ্ধতি নতুন থ্রেড সঞ্চালনের শুরু আহ্বান run()পদ্ধতি। start()পদ্ধতি অবিলম্বে ফেরৎ এবং নতুন থ্রেড স্বাভাবিকভাবে পর্যন্ত চলতে run()পদ্ধতি আয়।

থ্রেড ক্লাসের run()পদ্ধতিটি কিছুই করে না, সুতরাং সাব-ক্লাসগুলির কোডটি দ্বিতীয় থ্রেডে চালিত করার জন্য পদ্ধতিটিকে ওভাররাইড করা উচিত। যদি কোনও থ্রেড একটি রান্নেবল আর্গুমেন্টের সাথে ইনস্ট্যান্ট করা হয় তবে থ্রেডের run()পদ্ধতিটি run()পরিবর্তে নতুন থ্রেডে রান্নেবল অবজেক্টের পদ্ধতিটি কার্যকর করে।

আপনার থ্রেডেড প্রোগ্রামের প্রকৃতির উপর নির্ভর করে থ্রেড run()পদ্ধতিটিকে সরাসরি কল করা start()পদ্ধতিটির মাধ্যমে কল করার অনুরূপ আউটপুট দিতে পারে , তবে পরবর্তী ক্ষেত্রে কোডটি আসলে একটি নতুন থ্রেডে কার্যকর করা হয়।

উল্লেখ


তোমালাক উত্তর হিসাবে একই !! আপনি যদি কোথাও কোথাও রেফারেন্স দিয়ে থাকেন তবে দয়া করে তা উল্লেখ করুন !!
ব্যারি

The start() method returns immediately and the new thread normally continues until the run() method returns.যদি start()তাত্ক্ষণিকভাবে ফিরে আসে তবে কীভাবে run()চালিয়ে যাওয়া চালিয়ে যায় তা প্রদত্ত যে এটি নিজের থেকেই বলা হয়েছিলstart()
কেএনইউ

7

যদি প্রশ্নটি ছিল - "থ্রেড শুরুর পদ্ধতিটি সরাসরি রান পদ্ধতির পরিবর্তে কেন বলা হয়" তবে আমি নীচের উদাহরণ সহ উত্তর দিয়েছি। আশা করি তা স্পষ্ট হয়ে গেছে। নীচের উদাহরণে:

/*
By calling t1.start(), 
we are getting the main calling thread returned immediately 
after the t1.start() called and is ready to proceed for other 
operations.And the thread t1 starts executing the run method of the object r. 
Hence the the output will be:

      I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000

      I am done executing run method of testThread

*/


/* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing)
 its like a regular method call and the main thread will not return until the run method completes, 
 hence the output will be:

         I am done executing run method of testThread

         I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000

*/


class testThread implements Runnable{

 public void run()
 {
     for(int i=0;i<1000000;i++){} //a simple delay block to clarify.

     System.out.println("I am done executing run method of testThread");

 }  
}

public class mainClass{

   public static void main(String [] args)
    {
          testThread r = new testThread();
          Thread t1 = new Thread(r);
          t1.start();  /* Question is: can we call instead t1.run() */  
          System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000");

    }
}

5

যখন আপনি এটি সিঙ্ক্রোনালি চালাতে চান। রান মেথডে কল করা আসলে আপনাকে মাল্টি-থ্রেডিং দেয় না। প্রারম্ভিক পদ্ধতিটি একটি নতুন থ্রেড তৈরি করে যা রান পদ্ধতিটিকে কল করে।


3

আপনি যদি রান () এর সামগ্রীগুলি নির্বাহ করতে চান তবে আপনি অন্য কোনও পদ্ধতিতে চান। অবশ্যই কোনও থ্রেড শুরু করতে হবে না।


3

ধরে নেওয়া যায় যে আপনি স্টার্ট এবং রান পদ্ধতিটি ব্যবহার সম্পর্কে জানেন যেমন সিঙ্ক্রোনাস বনাম অ্যাসিনক্রোনাস; রান পদ্ধতিটি কেবল কার্যকারিতা পরীক্ষা করতে ব্যবহার করা যেতে পারে।

প্লাস কিছু পরিস্থিতিতে একই থ্রেড বর্গটি একটির রান পদ্ধতিতে এবং অন্যটির শুরুর পদ্ধতিটি চাওয়ার মাধ্যমে দুটি পৃথক বস্তু থাকার সাথে সিঙ্ক এবং অ্যাসিঞ্চ কার্যকারিতা প্রয়োজনীয়তা সহ দুটি পৃথক স্থানে ব্যবহার করা যেতে পারে।


2

কমপক্ষে JVM 1.6 তে, কিছুটা পরীক্ষা করে চালানো হয় এবং তাকে স্থানীয়ভাবে বলা হয়:

 public synchronized void start() {
        /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added 
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
    }

    private native void start0();

2

উপরের দুর্দান্ত মন্তব্যে কেবল একটি নোট: কখনও কখনও আপনার একটি মাল্টি-থ্রেড কোড লিখুন যা বিভিন্ন থ্রেড চালানোর জন্য "শুরু" পদ্ধতি ব্যবহার করে। আপনি যদি ডিবাগিংয়ের জন্য "রান" ("স্টার্টের পরিবর্তে") ব্যবহার করেন তবে কোডটি সিঙ্ক্রোনালি চালানো এবং এটির থেকে খুব সহজেই ডিবাগিং করা সম্ভব হলে আপনি এটি অনেক সহজ পাবেন।


-1
public class TestClass implements Runnable {
    public static void main(String[] args) {
        TestClass tc = new TestClass();

        Thread t1 = new Thread(tc);
        System.out.println("Before Starting Thread " + Thread.currentThread().hashCode());
        t1.start();
        System.out.println("After Starting Thread " + Thread.currentThread().hashCode());
    }

    @Override
    public void run() {
        System.out.println("TestClass Run method is  Running with thread " + Thread.currentThread().hashCode());        
    }
}

হাই ফ্রনজ, চেক আউট করুন এবং উপরের উদাহরণটি চালিয়ে যান স্পষ্টভাবে প্রথমে t1.start () দিয়ে চালানোর জন্য এবং হ্যাশকোড এবং পরের বার t1.run () এবং chk হ্যাশকোডগুলি দেখুন
অবতার গিরাজে

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