ජාවා හි “ධාවනය කළ හැකි” එදිරිව “නූල් දිගු කරයි”


2128

මම ජාවා හි නූල් සමඟ ගත කළ කාලයේ සිට, නූල් ලිවීමට මෙම ක්‍රම දෙක මට හමු විය:

සමග implements Runnable:

public class MyRunnable implements Runnable {
    public void run() {
        //Code
    }
}
//Started with a "new Thread(new MyRunnable()).start()" call

හෝ, සමඟ extends Thread:

public class MyThread extends Thread {
    public MyThread() {
        super("MyThread");
    }
    public void run() {
        //Code
    }
}
//Started with a "new MyThread().start()" call

මෙම කේත කොටස් දෙකෙහි සැලකිය යුතු වෙනසක් තිබේද?


57
මෙම ප්‍රශ්නයට ස්තූතියි, පිළිතුරු මගින් මා තුළ තිබූ වැරදි වැටහීම් රාශියක් ඉවත් විය. SO පැවතීමට පෙර ජාවා නූල් කිරීමට නිවැරදි ක්‍රමය සොයා බැලූ අතර එහි වැරදි තොරතුරු / යල් පැන ගිය තොරතුරු රාශියක් තිබුණි.
ජේම්ස් මැක් මහෝන්

5
ඔබට නූල් දිගු කිරීමට අවශ්‍ය විය හැකි එක් හේතුවක් තිබේ ( නමුත් මම එය නිර්දේශ නොකරමි ), ඔබට පූර්වයෙන් හැසිරවිය හැකිය interrupt(). නැවතත්, එය අදහසකි, එය නිවැරදි අවස්ථාවෙහිදී ප්‍රයෝජනවත් විය හැකිය, කෙසේ වෙතත් මම එය නිර්දේශ නොකරමි.
bestsss

මනාව පැහැදිලි කර ඇති පිළිතුරද කරුණාකර බලන්න: stackoverflow.com/q/5562720/285594

est බෙස්ට්ස්, මම උත්සාහ කරන්නේ බාධා කිරීම් () හැසිරවීම සම්බන්ධයෙන් ඔබ අදහස් කරන්නේ කුමක්ද යන්න ප්‍රහේලිකාවක් කිරීමටයි. ඔබ ක්‍රමය ඉක්මවා යාමට උත්සාහ කරනවාද?
බොබ් ක්‍රොස්

8
ඔව්. කේතයට අනුව, පන්තියේ නූල් A ට ඕනෑම පන්තියක් දීර් extend කළ හැකි අතර පංතියේ නූල් බී වෙනත් පන්තියක් දීර් extend කළ නොහැක
මනි දීපක්

Answers:


1677

ඔව්: Runnableඑය කිරීමට වඩාත් කැමති ක්‍රමය ක්‍රියාත්මක කිරීමයි, IMO. ඔබ ඇත්තටම නූල් හැසිරීම විශේෂීකරණය නොකරයි. ඔබ එය ක්‍රියාත්මක කිරීමට යමක් ලබා දෙනවා. ඒ කියන්නේ සංයුතිය යනු දාර්ශනිකව “පිරිසිදු” යන්නයි.

දී ප්රායෝගික කොන්දේසි, එය ඔබ ක්රියාත්මක කළ හැකි බවයි Runnableහා මෙන්ම තවත් පන්තියෙන් දීර්ඝ.


151
හරියටම, හොඳින් දාන්න. ත්‍රෙඩ් එක දිගු කිරීමෙන් එය නැවත ලිවීමට අප උත්සාහ කරන්නේ කුමන හැසිරීමද? මම තර්ක කරන්නේ බොහෝ අය කිසිදු හැසිරීමක් නැවත ලිවීමට උත්සාහ නොකරන නමුත් නූල් වල හැසිරීම භාවිතා කිරීමට උත්සාහ කරන බවයි.
කොක්ක

87
පැති අදහස් දැක්වීමක් ලෙස, ඔබ නූල් එකක් ක්ෂණිකව සකසා එහි ආරම්භක () ක්‍රමය නොකියන්නේ නම් ඔබ ජාවා <5 හි මතක කාන්දුවක් නිර්මාණය කරයි (මෙය ධාවනය කළ හැකි දේ සමඟ සිදු නොවේ): stackoverflow.com/questions/107823/…
කොලෝමා

25
Runnable හි ඇති එක් කුඩා වාසියක් නම්, යම් යම් තත්වයන් යටතේ ඔබ ඒ ගැන තැකීමක් නොකරන්නේ නම් හෝ නූල් භාවිතා කිරීමට අකමැති නම් සහ ඔබට කේතය ක්‍රියාත්මක කිරීමට අවශ්‍ය නම්, ඔබට ධාවනය () අමතන්න විකල්පයක් ඇත. උදා (ඉතා අත්කම්) if (numberCores > 4) myExecutor.excute(myRunnable); else myRunnable.run()
පරිශීලක 949300

10
@ user949300 ඔබටද එය කළ හැකි extends Threadඅතර ඔබට නූල් දැමීම අවශ්‍ය නොවන්නේ නම් ඇයි ඔබ එය ක්‍රියාත්මක කරන්නේ Runnable...
m0skit0

30
සියෙරා සහ බේට්ස් යන අක්ෂර වින්‍යාසය සඳහා, ධාවනය කළ හැකි ක්‍රියාවට නැංවීමේ ප්‍රධාන වාසියක් නම්, ඔබ වාස්තු විද්‍යාත්මකව “රැකියාව” “ධාවකයා” වෙතින් වෙන් කිරීමයි.
8bitjunkie

570

tl; dr: ක්‍රියාත්මක කළ හැකි ධාවනය වඩා හොඳය. කෙසේ වෙතත්, අවවාදය වැදගත් ය

පොදුවේ ගත් කල, මම නිර්දේශ කරන්නේ ඒ Runnableවෙනුවට Threadඔබේ වැඩ කටයුතු ලිහිල්ව හා සමගාමී මුදල් තේරීම සමඟ පමණක් තබා ගැනීමට ඉඩ සලසන බැවිනි. නිදසුනක් ලෙස, ඔබ එය භාවිතා කර Runnableපසුව තීරණය කරන්නේ නම් එය ඇත්ත වශයෙන්ම එය අයිති කර Threadගත යුතු නොවේ නම් , ඔබට නූල් ඒ.රුන් () අමතන්න.

කේවියට්: අමු නූල් භාවිතය මම දැඩි ලෙස අධෛර්යමත් කරමි. භාවිතය මම බොහෝ කැමති Callables හා FutureTasks (: "ඒ cancellable අසමමිතික ගණනය" යන javadoc සිට). අමු නූල් ගොඩවල් වලට වඩා කල් ඉකුත්වීම, නිසි අවලංගු කිරීම සහ නූතන සමගාමී ආධාරකයේ නූල් සංචලනය මට ප්‍රයෝජනවත් වේ.

පසු විපරම්: යම් කෙනෙක් FutureTaskඉදිකිරීමටත් ඔබ (ඔබ සමඟ වඩාත් පහසු මොකක්ද නම්) Runnables භාවිතා තවමත් නවීන සමගාමී මෙවලම් යහපත ලබා ගැනීමට ඉඩ සලසා දෙන. Javadoc උපුටා දැක්වීමට :

ඔබට විශේෂිත ප්‍රති result ලයක් අවශ්‍ය නොවේ නම්, පෝරමයේ ඉදිකිරීම් භාවිතා කිරීම සලකා බලන්න:

Future<?> f = new FutureTask<Object>(runnable, null)

එබැවින්, අපි ඒවා runnableඔබේ වෙනුවට ආදේශ කළහොත් threadA, අපට පහත සඳහන් දේ ලැබේ:

new FutureTask<Object>(threadA, null)

Runnables වෙත සමීපව සිටීමට ඔබට ඉඩ සලසන තවත් විකල්පයක් වන්නේ ThreadPoolExecutor ය . "අනාගතයේදී යම් වේලාවක දී ලබා දී ඇති කාර්යය" ක්‍රියාත්මක කිරීම සඳහා ඔබට ක්‍රියාත්මක කළ හැකි ක්‍රමය ක්‍රියාත්මක කළ හැකිය .

ඔබ නූල් තටාකයක් භාවිතා කිරීමට උත්සාහ කිරීමට කැමති නම්, ඉහත කේත කැබැල්ල පහත සඳහන් දේට සමාන වනු ඇත ( Executor.newCachedThreadPool () කර්මාන්තශාලා ක්‍රමය භාවිතා කරමින්):

ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());

40
IMHO පිළිගත් පිළිතුරට වඩා මෙය හොඳය. එක් දෙයක්: ඔබ සතුව ඇති කේතයේ කොටස ක්‍රියාත්මක කරන්නා වසා නොදමන අතර මිනිසුන් මෙය වැරදියට වටහා ගන්නා ප්‍රශ්න මිලියන ගණනක් මම දකිමි, යම් කාර්යයක් ආරම්භ කිරීමට අවශ්‍ය සෑම අවස්ථාවකම නව විධායක නිලධාරියෙකු නිර්මාණය කරමි. esස්ථිතික (හෝ එන්නත් කරන ලද) ක්ෂේත්‍රයක් ලෙස වඩා හොඳ වනු ඇති බැවින් එය එක් වරක් පමණක් නිර්මාණය වේ.
artbristol

8
@artbristol, ස්තූතියි! නව ක්‍රියාත්මක කරන්නාට මම එකඟ නොවෙමි (අපගේ කේතයේ ඔබ යෝජනා කරන දේ අපි කරන්නෙමු). මුල් පිළිතුර ලිවීමේදී, මම උත්සාහ කළේ මුල් කැබැල්ලට සමාන අවම කේතයක් ලිවීමටයි. මෙම පිළිතුරු කියවන බොහෝ පා readers කයන් ඒවා පැනීමේ ලකුණු ලෙස භාවිතා කරනු ඇතැයි අපි බලාපොරොත්තු විය යුතුය. මම javadoc වෙනුවට ආදේශකයක් ලිවීමට උත්සාහ නොකරමි. මම ඒ සඳහා අලෙවිකරණ ද්‍රව්‍ය effectively ලදායී ලෙස ලියමි: ඔබ මෙම ක්‍රමයට කැමති නම්, අප විසින් පිරිනමනු ලබන අනෙකුත් සියලුම විශිෂ්ට දේ ඔබ දැක ගත යුතුය ...!
බොබ් ක්‍රොස්

3
මම මේ ගැන අදහස් දැක්වීම තරමක් ප්‍රමාද බව මම දනිමි, නමුත් FutureTaskdirectly ජුව ගනුදෙනු කිරීම සාමාන්‍යයෙන් ඔබට කිරීමට අවශ්‍ය දේ නොවේ. ExecutorServiceගේ සුදුසු නිර්මාණය වනු ඇත Futureඔබ වෙනුවෙන් විට ඔබ submitඑය Runnable/ Callableඔවුන්ට. සඳහා ඒ හා සමානව ScheduledExecutorServiceහි හා ScheduledFutureවිට ඔබ scheduleඑය Runnable/ Callable.
පවර්ලර්

3
Ower පවර්ලර්ඩ්, මගේ අභිප්‍රාය වූයේ OP වලට ගැලපෙන කේත කොටස් හැකි තරම් සමීප කිරීමයි. නව FutureTask ප්‍රශස්ත නොවන බව මම එකඟ වෙමි, නමුත් එය පැහැදිලි කිරීමේ අරමුණු සඳහා පැහැදිලි ය.
බොබ් ක්‍රොස්

260

කතාවේ සදාචාරය:

ඔබට යම් හැසිරීමක් ඉක්මවා යාමට අවශ්‍ය නම් පමණක් උරුම වන්න.

නැතහොත් එය මෙසේ කියවිය යුතුය:

අඩු උරුමයක්, අතුරු මුහුණත වැඩියෙන්.


1
ඔබ සමගාමී ධාවන වස්තුවක් සෑදීමට පටන් ගන්නේ නම් මෙය සැමවිටම ප්‍රශ්නය විය යුතුය! ඔබට Thread Object funtions පවා අවශ්‍යද?
ලිබර්ටි

4
නූල් වලින් උරුම වන විට, සෑම විටම පාහේ run()ක්‍රමයේ හැසිරීම අභිබවා යාමට අවශ්‍ය වේ .
වොරන් ඩිව්

1
ඔබ හැසිරීම අබිබවා යා නොහැකි java.lang.Threadආධිපත්යධාරී විසින් run()ක්රමය. එවැනි අවස්ථාවකදී start()මා අනුමාන කරන ක්‍රමය ඉක්මවා යා යුතුය . සාමාන්‍යයෙන් ඔබ java.lang.Threadඔබේ ක්‍රියාවිරහිත කිරීමේ run()ක්‍රමය ක්‍රමයට එන්නත් කිරීමෙන් හැසිරීම නැවත භාවිතා කරයි .
sura2k

උරුමය යනු යම් හැසිරීමක් ඉක්මවා යාම සඳහා පමණක් නොව, පොදු හැසිරීම් භාවිතා කිරීම ද වේ. එය ප්‍රතිවිරුද්ධ, වඩා අභිබවා යන, නරක ධූරාවලියයි.
peja

232

හොඳයි බොහෝ හොඳ පිළිතුරු, මට මේ ගැන තවත් එකතු කිරීමට අවශ්‍යයි. මෙය තේරුම් ගැනීමට උපකාරී වේ Extending v/s Implementing Thread.
විස්තාරණය කිරීම පන්ති ලිපිගොනු දෙකක් ඉතා සමීපව බැඳ තබන අතර කේත සමඟ කටයුතු කිරීමට තරමක් අපහසු වේ.

ප්රවේශයන් දෙකම එකම කාර්යයක් කරන නමුත් යම් වෙනස්කම් තිබේ.
වඩාත් පොදු වෙනස වන්නේ

  1. ඔබ නූල් පන්තිය දීර් extend කරන විට, ඔබට අවශ්‍ය වෙනත් පන්තියක් දීර් extend කළ නොහැක. (ඔබ දන්නා පරිදි, ජාවා එක් පන්තියකට වඩා උරුම කර ගැනීමට ඉඩ නොදේ).
  2. ඔබ Runnable ක්‍රියාත්මක කරන විට, අනාගතයේදී හෝ දැන් වෙනත් පන්තියක් දීර් extend කිරීමට ඔබේ පන්තියට ඉඩ ඉතිරි කර ගත හැකිය.

කෙසේ වෙතත්, ධාවනය කළ හැකි සහ නූල් දිගු කිරීම අතර ඇති එක් සැලකිය යුතු වෙනසක් එයයි
by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.

පහත උදාහරණය වඩාත් පැහැදිලිව තේරුම් ගැනීමට ඔබට උපකාරී වනු ඇත

//Implement Runnable Interface...
 class ImplementsRunnable implements Runnable {

private int counter = 0;

public void run() {
    counter++;
    System.out.println("ImplementsRunnable : Counter : " + counter);
 }
}

//Extend Thread class...
class ExtendsThread extends Thread {

private int counter = 0;

public void run() {
    counter++;
    System.out.println("ExtendsThread : Counter : " + counter);
 }
}

//Use the above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {

public static void main(String args[]) throws Exception {
    // Multiple threads share the same object.
    ImplementsRunnable rc = new ImplementsRunnable();
    Thread t1 = new Thread(rc);
    t1.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    Thread t2 = new Thread(rc);
    t2.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    Thread t3 = new Thread(rc);
    t3.start();

    // Creating new instance for every thread access.
    ExtendsThread tc1 = new ExtendsThread();
    tc1.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    ExtendsThread tc2 = new ExtendsThread();
    tc2.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    ExtendsThread tc3 = new ExtendsThread();
    tc3.start();
 }
}

ඉහත වැඩසටහනේ ප්‍රතිදානය.

ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1

ධාවනය කළ හැකි අතුරුමුහුණත් ප්‍රවේශයේදී, පන්තියක එක් අවස්ථාවක් පමණක් නිර්මාණය වන අතර එය විවිධ නූල් මගින් බෙදාගෙන ඇත. එබැවින් සෑම නූල් ප්‍රවේශයක් සඳහාම කවුන්ටරයේ වටිනාකම වැඩි වේ.

ත්‍රෙඩ් පංති ප්‍රවේශය වන අතර, සෑම නූල් ප්‍රවේශයක් සඳහාම වෙනම අවස්ථාවක් නිර්මාණය කළ යුතුය. එබැවින් සෑම පන්ති අවස්ථාවන් සඳහාම වෙනස් මතකයක් වෙන් කර ඇති අතර සෑම එකක්ම වෙනම කවුන්ටරයක් ​​ඇත, අගය එක හා සමාන වේ, එයින් අදහස් වන්නේ කිසිදු වස්තුවක් යොමු නොවන බැවින් වර්ධකයක් සිදු නොවන බවයි.

ධාවනය කළ හැකි භාවිතා කරන්නේ කවදාද?
නූල් සමූහයෙන් එකම සම්පත් වෙත ප්‍රවේශ වීමට ඔබට අවශ්‍ය විට ධාවනය කළ හැකි අතුරු මුහුණත භාවිතා කරන්න. මෙහි නූල් පන්තිය භාවිතා කිරීමෙන් වළකින්න, මන්ද බහු වස්තු නිර්මාණය වැඩි මතකයක් පරිභෝජනය කරන අතර එය ඉහළ කාර්ය සාධනයක් බවට පත්වේ.

Runnable ක්‍රියාත්මක කරන පන්තියක් නූල් සහ පන්තියක් නොවේ. ධාවනය කළ හැකි නූලක් බවට පත්වීම සඳහා, ඔබ නූල් පිළිබඳ උදාහරණයක් නිර්මාණය කර ඉලක්කය ලෙස ඉදිරියට යා යුතුය.

බොහෝ අවස්ථාවන්හීදී, ධාවනය කළ හැකි අතුරුමුහුණත භාවිතා කළ යුත්තේ ඔබ run()ක්‍රමවේදය ඉක්මවා යාමට සැලසුම් කරන්නේ නම් සහ වෙනත් නූල් ක්‍රම නොමැති නම් පමණි . මෙය වැදගත් වන්නේ පංතියේ මූලික හැසිරීම වෙනස් කිරීමට හෝ වැඩි දියුණු කිරීමට ක්‍රමලේඛකයා අදහස් කරන්නේ නම් මිස පන්ති උප කාණ්ඩයට නොගත යුතු බැවිනි.

සුපිරි පන්තියක් දීර් extend කිරීමේ අවශ්‍යතාවයක් ඇති විට, නූල් පන්තිය භාවිතා කිරීමට වඩා ධාවනය කළ හැකි අතුරු මුහුණත ක්‍රියාත්මක කිරීම වඩාත් යෝග්‍ය වේ. නූල් සෑදීම සඳහා ධාවනය කළ හැකි අතුරුමුහුණත ක්‍රියාත්මක කරන අතරතුර අපට වෙනත් පන්තියක් දීර් extend කළ හැකි බැවිනි.

මම හිතනවා මේක උදව් වෙයි කියලා!


42
ඔබේ කේතය ඉතා වැරදිය. මම කිව්වේ, එය කරන්නේ එයයි, නමුත් ඔබ පෙන්වීමට අදහස් කළ දේ නොවේ.
zEro

40
පැහැදිලි කර ගැනීම සඳහා: ධාවනය කළ හැකි නඩුව සඳහා ඔබ එකම නූල් කිහිපයක් ආරම්භ කිරීමට භාවිතා කළ හැකි අතර, නූල් නඩුව සඳහා ඔබ විවිධ විස්තාරණ ත්‍රෙඩ් අවස්ථා නිර්මාණය කරන අතර එය පැහැදිලිවම ඔබ පෙන්වූ හැසිරීමට හේතු වේ. ඔබේ ප්‍රධාන ක්‍රමයේ දෙවන භාගය විය යුත්තේ: ExtendsThread et = new ExtendsThread(); Thread tc1 = new Thread(et); tc1.start(); Thread.sleep(1000); Thread tc2 = new Thread(et); tc2.start(); Thread.sleep(1000); Thread tc3 = new Thread(et); tc3.start(); එය වඩා පැහැදිලිද?
zEro

20
ඔබේ අභිප්‍රාය මට තවම වැටහී නැත, නමුත් මගේ අදහස වූයේ ඔබ ExtendsThread හි අවස්ථා කිහිපයක් නිර්මාණය කළහොත් - ඒවා සියල්ලම 1 ආපසු එනු ඇත (ඔබ පෙන්වා ඇති පරිදි). ධාවන පථයේ එකම දේ කිරීමෙන් ඔබට එකම ප්‍රති results ල ලබා ගත හැකිය, එනම් ක්‍රියාත්මක කිරීම් ක්‍රියාත්මක කළ නොහැකි අවස්ථා කිහිපයක් නිර්මාණය කිරීම.
zEro

3
@zEro හායි, මම අනාගතයේ සිට. ඔබේ කේතයේ අනුවාදය ද Threadවැඩි වෙමින් පවතින බැවින්, එම ප්‍රකාශය by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instanceවැරදියි ද? එසේ නොවේ නම්, මෙය පෙන්නුම් කරන නඩුව කුමක්ද?
නපුරු රෙදි සෝදන යන්ත්‍රය

4
මෙහි පළ කර ඇති කේතය නොමඟ යවන අතර එය හිසරදයක් විය හැකිය. එය ටිකක් ඉවත් කිරීම ගැන @zEro ට ස්තූතියි.
නිකොස්

78

මා පුදුමයට පත් කරන එක් දෙයක් නම් තවමත් සඳහන් කර නොමැති අතර එය ක්‍රියාත්මක Runnableකිරීම ඔබේ පන්තිය වඩාත් නම්‍යශීලී කරයි.

ඔබ නූල් දිගු කළහොත් ඔබ කරන ක්‍රියාව සැමවිටම ත්‍රෙඩ් එකක වනු ඇත. කෙසේ වෙතත්, ඔබ Runnableඑය ක්‍රියාත්මක කරන්නේ නම් එය එසේ විය යුතු නැත. ඔබට එය ත්‍රෙඩ් එකකින් ධාවනය කළ හැකිය, නැතහොත් එය යම් ආකාරයක ක්‍රියාත්මක කිරීමේ සේවාවක් වෙත යැවිය හැකිය, නැතහොත් එය තනි නූල් යෙදුමක් තුළ කර්තව්‍යයක් ලෙස සම්මත කළ හැකිය (සමහර විට පසුකාලීනව ක්‍රියාත්මක විය හැකි නමුත් එකම ත්‍රෙඩ් එකක). Runnableඔබ ඔබම බැඳ තබනවාට වඩා ඔබ භාවිතා කරන්නේ නම් විකල්පයන් බොහෝ විවෘත වේ Thread.


6
හොඳයි, ඔබට ඇත්ත වශයෙන්ම Threadවස්තුවක් සමඟ එකම දේ කළ හැකිය Thread implements Runnable… ;-) නමුත් මේ දේවල් කිරීම වඩා හොඳ යැයි හැඟෙන්නේ Runnableඒවා සමඟ ඒවා කරනවාට වඩා Thread!
siegi

8
ඇත්ත, නමුත් Threadඔබට අවශ්‍ය නොවන අමතර දේවල් රාශියක් එකතු කරයි, බොහෝ අවස්ථාවලදී අවශ්‍ය නොවේ. ඔබ සැබවින්ම කරන දෙයට ගැලපෙන අතුරු මුහුණත ක්‍රියාත්මක කිරීමට වඩා හොඳය.
හර්ම්ස්

75

ඔබට Runnableවෙනත් පංතියක් ක්‍රියාත්මක කිරීමට හෝ දීර් extend කිරීමට අවශ්‍ය නම් අතුරු මුහුණත වඩාත් යෝග්‍ය වේ, එසේ නොමැතිනම් වෙනත් පන්තියක් දීර් extend කිරීමට හෝ ක්‍රියාත්මක කිරීමට ඔබට අවශ්‍ය නැතිනම් Threadපන්තිය වඩාත් යෝග්‍ය වේ.

වඩාත් පොදු වෙනස වන්නේ

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඔබ extends Threadපන්ති කරන විට , ඔබට අවශ්‍ය වෙනත් පන්තියක් දීර් extend කළ නොහැක. (ඔබ දන්නා පරිදි, ජාවා එක් පන්තියකට වඩා උරුම කර ගැනීමට ඉඩ නොදේ).

ඔබ සිටින විට implements Runnable, අනාගතයේදී හෝ දැන් වෙනත් පන්තියක් දීර් extend කිරීමට ඔබේ පන්තියට ඉඩ ඉතිරි කර ගත හැකිය.

  • ජාවා බහු උරුමයන්ට සහාය නොදක්වයි, එයින් අදහස් කරන්නේ ඔබට ජාවා හි එක් පන්තියක් පමණක් දීර් extend කළ හැකි වන අතර එමඟින් ඔබ නූල් පන්තිය දීර් extended කළ පසු ඔබට අවස්ථාව අහිමි වූ අතර ජාවා හි වෙනත් පන්තියක් දීර් extend කිරීමට හෝ උරුම කර ගැනීමට නොහැකි විය.

  • වස්තු-නැඹුරු වැඩසටහන්කරණයේදී, සාමාන්‍යයෙන් පන්තියක් දිගු කිරීම, නව ක්‍රියාකාරිත්වය එකතු කිරීම සහ හැසිරීම් වෙනස් කිරීම හෝ වැඩිදියුණු කිරීම යන්නෙන් අදහස් වේ. අපි Thread හි කිසිදු වෙනස් කිරීමක් නොකරන්නේ නම් ඒ වෙනුවට ධාවනය කළ හැකි අතුරු මුහුණත භාවිතා කරන්න.

  • ධාවනය කළ හැකි අතුරුමුහුණත නිරූපණය කරන්නේ සරල නූල් හෝ ක්‍රියාත්මක කරන්නන් හෝ වෙනත් ආකාරයකින් ක්‍රියාත්මක කළ හැකි කාර්යයකි. එබැවින් කාර්යය ත්‍රෙඩ් එකට වඩා ධාවනය කළ හැකි ලෙස තාර්කිකව වෙන් කිරීම හොඳ නිර්මාණ තීරණයක්.

  • කාර්යය ධාවනය කළ හැකි ලෙස වෙන් කිරීම යනු අපට එම කාර්යය නැවත භාවිතා කළ හැකි අතර එය විවිධ මාධ්‍යයන්ගෙන් ක්‍රියාත්මක කිරීමේ නිදහස ද ඇත. ත්‍රෙඩ් එකක් සම්පුර්ණ වූ පසු එය නැවත ආරම්භ කළ නොහැක. කාර්යය සඳහා නැවතත් ධාවනය කළ හැකි එදිරිව නූල්, ධාවනය කළ හැකි ජයග්‍රාහකයා වේ.

  • ජාවා නිර්මාණකරුවා මෙය හඳුනාගෙන ඇති අතර, ක්‍රියාත්මක කරන්නන් විසින් ධාවනය කළ හැකි කාර්යය ලෙස පිළිගන්නා අතර එම කාර්යය ඉටු කරන සේවක නූල් ඔවුන් සතුව ඇත.

  • සියලු නූල් ක්‍රම උරුම කර ගැනීම යනු ක්‍රියාත්මක කළ හැකි කාර්යයන් සමඟ පහසුවෙන් කළ හැකි කාර්යයක් නිරූපණය කිරීම සඳහා අතිරේක පොදු කාර්යයකි.

අනුග්‍රහය javarevisited.blogspot.com වෙතින්

මේවා ජාවා හි නූල් සහ ධාවනය කළ හැකි අතර කැපී පෙනෙන වෙනස්කම් විය. Thread vs Runnable හි වෙනත් වෙනස්කම් ඔබ දන්නේ නම් කරුණාකර එය අදහස් හරහා බෙදා ගන්න. මෙම තත්වය සඳහා මම පුද්ගලිකව Runnable Over Thread භාවිතා කරන අතර ඔබේ අවශ්‍යතාවය මත ධාවනය කළ හැකි හෝ කැඳවිය හැකි අතුරු මුහුණතක් භාවිතා කිරීමට නිර්දේශ කරමි.

කෙසේ වෙතත්, සැලකිය යුතු වෙනස වන්නේ.

ඔබ extends Threadපන්ති කරන විට , ඔබේ සෑම නූලක්ම අද්විතීය වස්තුවක් නිර්මාණය කර එය සමඟ ඇසුරු කරයි. ඔබ implements Runnable, එය එකම වස්තුව බහු නූල් වලට බෙදා ගනී.


73

ඇත්තටම, එය සංසන්දනය කිරීමට නැණවත් දෙයක් නෙවෙයි Runnableහා Threadඑකිනෙකා සමග.

මෙම දෙදෙනා Wheel and Engineමෝටර් රථ සම්බන්ධතාවයට සමානව බහු නූල්වල යැපීමක් හා සම්බන්ධතාවයක් ඇත .

මම කියන්නේ, පියවර දෙකක් සහිත බහු-නූල් දැමීම සඳහා ඇත්තේ එක් මාර්ගයක් පමණි. මගේ අදහස ඉදිරිපත් කිරීමට මට ඉඩ දෙන්න.

ධාවනය කළ හැකි: එය
ක්‍රියාත්මක කිරීමේදී interface Runnableඑයින් අදහස් වන්නේ ඔබ run ableවෙනස් ත්‍රෙඩ් එකක යමක් නිර්මාණය කරන බවයි. දැන් නූල් එකක් තුළ ධාවනය කළ හැකි යමක් නිර්මාණය කිරීම (නූල් එකක් තුළ ධාවනය කළ හැකි), නූල් එකක් සෑදීම යන්නෙන් අදහස් නොවේ.
එබැවින් පන්තිය MyRunnableයනු void runක්‍රමවේදයක් සහිත සාමාන්‍ය පන්තියකි . එහි වස්තූන් සාමාන්‍ය වස්තූන් වන අතර එය ක්‍රමයක් පමණක් ඇති runඅතර එය සාමාන්‍යයෙන් කැඳවූ විට ක්‍රියාත්මක වේ. (අපි වස්තුව නූල් එකකින් සම්මත නොකරන්නේ නම්).

නූල්:,
class Thread මම කියන්නේ නව ත්‍රෙඩ් එකක් ආරම්භ කිරීමේ හැකියාව ඇති විශේෂ පන්තියක් එහි start()ක්‍රමවේදය හරහා බහු-නූල් දැමීම සැබවින්ම සක්‍රීය කරයි .

සංසන්දනය කිරීම නැණවත් නොවන්නේ ඇයි?
බහු නූල් දැමීම සඳහා අපට ඒ දෙකම අවශ්‍ය නිසා.

බහු නූල් දැමීම සඳහා අපට කරුණු දෙකක් අවශ්‍ය වේ:

  • ත්‍රෙඩ් එකක් තුළ ධාවනය කළ හැකි දෙයක් (ධාවනය කළ හැකි).
  • නව නූල් (නූල්) ආරම්භ කළ හැකි දෙයක්.

එබැවින් තාක්ෂණික හා න්‍යායාත්මකව මේ දෙකම නූල් එකක් ආරම්භ කිරීමට අවශ්‍ය වේ, එකක් ධාවනය වන අතර තවත් එකක් එය ධාවනය කරයි ( Wheel and Engineමෝටර් වාහනය මෙන් ).

ඔබ සමඟ නූල් ආරම්භ කල නොහැකි ඒකයි MyRunnableඔබ ක උදාහරණයක් එය සම්මත කිරීමට අවශ්ය Thread.

නමුත් නූල් තැනීමට හා ක්‍රියාත්මක කිරීමට හැකි class Threadවන්නේ පංතිය Threadක්‍රියාත්මක වන Runnableනිසා පමණක් Threadවන අතර එය Runnableඅභ්‍යන්තරයක් බව අපි කවුරුත් දනිමු .

අවසාන වශයෙන් Threadසහ Runnableතරඟකරුවන් හෝ ප්‍රතිස්ථාපනය නොකිරීම සඳහා බහු තෙරපුම සඳහා එකිනෙකාට අනුපූරක වේ.


3
හරියටම! මෙය පිළිගත් පිළිතුර විය යුතුය. BTW මම හිතන්නේ ප්‍රශ්නය සංස්කරණය කර ඇති අතර ThreadAතවදුරටත් තේරුමක් නැත
idelvall

පිළිගත් පිළිතුර ඔබගේ ප්‍රතිචාරයට ස්තූතියි. අයිඩෙල්වාල්
සයිෆ්

හොඳම පිළිතුර! ස්තූතියි!
මයිකල්

44

ඔබ Runnable ක්රියාත්මක කළ යුතු, නමුත් ඔබට ජාවා 5 හෝ ඊට වැඩි මත ධාවනය කරන්නේ නම්, ඔබ එය ආරම්භ නොකළ යුතුය new Threadනමුත් භාවිතා ExecutorService වෙනුවට. වැඩි විස්තර සඳහා බලන්න: ජාවා හි සරල නූල් ක්‍රියාත්මක කරන්නේ කෙසේද .


5
ඔබට තනි ත්‍රෙඩ් එකක් දියත් කිරීමට අවශ්‍ය නම් ක්‍රියාත්මක කරන්නාගේ සේවය එතරම් ප්‍රයෝජනවත් වනු ඇතැයි මම නොසිතමි.
පවර්ලර්ඩ්

1
මා ඉගෙන ගත් දෙයින් යමෙක් පොදුවේ පොදුවේ නූල් එකක් ආරම්භ නොකළ යුතුය. මන්දයත් එය ක්‍රියාත්මක කිරීමේ සේවයට භාර දීමෙන් සියල්ල පාලනය කළ හැකි වනු ඇත (වැනි, නූල් අත්හිටුවීමට බලා සිටීම වැනි). එසේම, එය තනි නූල් එකක් ගැන අඟවන කිසිම ප්‍රශ්නයක් මා දකින්නේ නැත.
ෆේබියන් ස්ටීග්

4
ඕනෑම බහු-නූල් භාවිතා කිරීමෙන් ඇති ප්‍රයෝජනය කුමක්ද? එය තනි නූල් එකක් වනු ඇති බව අප දන්නවා නම්. එබැවින් අපි සතුව නූල් කිහිපයක් ඇති අතර මෙම පිළිතුර ඉතා වටිනා යැයි සිතමු.
zEro

1
EzEro මට හොඳටම විශ්වාසයි එක් සිදුවීමක් පිටත් කිරීමේ නූල් එකක් පමණක් ඇති බව. වෙනම නූල් එකක් තිබීම හොඳම නමුත් බහුකාර්යයක් තිබීම හොඳම නොවන එකම අවස්ථාව එය යැයි මට සැකයි.
porcoesphino

33

මම විශේෂ expert යෙක් නොවෙමි, නමුත් නූල් දිගු කිරීම වෙනුවට ධාවනය කළ හැකි ක්‍රියාත්මක කිරීමට එක් හේතුවක් ගැන මට සිතිය හැකිය: ජාවා සහාය දක්වන්නේ තනි උරුමයකට පමණි, එබැවින් ඔබට එක් පන්තියක් පමණක් දීර් extend කළ හැකිය.

සංස්කරණය කරන්න: මෙය මුලින් පැවසුවේ "අතුරු මුහුණතක් ක්‍රියාත්මක කිරීමට අඩු සම්පත් අවශ්‍ය බවයි." එසේම, නමුත් ඔබ නව ත්‍රෙඩ් නිදසුනක් එක් ආකාරයකින් නිර්මාණය කළ යුතුය, එබැවින් මෙය වැරදිය.


ධාවනය කළ හැකි විට අපට ජාල ඇමතුම් ලබා ගත නොහැක, එසේ ද? මට android.os.NetworkOnMainThreadException ඇති බැවින්. නමුත් නූල් භාවිතා කිරීමෙන් මට ජාල ඇමතුම් ලබා ගත හැකිය. මම වැරදියි නම් කරුණාකර මාව නිවැරදි කරන්න.
නබීල් තෝබානි

Ab නබීල් තෝබානි සාමාන්‍ය ජාවා එය ගණන් ගන්නේ නැත, නමුත් එය ඇන්ඩ්‍රොයිඩ් මෙන් පෙනේ. මට කියන්නට තරම් ඇන්ඩ්‍රොයිඩ් ගැන හුරුපුරුදු නැත.
පවර්ලර්ඩ්

1
Ab නබීල් තෝබානි ඇත්තෙන්ම ඔබට පුළුවන්. බොහෝ විට ඔබ ඔබේ ධාවනය කළ හැකි දේ සමඟ නූල් සාදන්නේ නැත.
m0skit0

20

තුන්වන ක්‍රමයක් ඇතැයි මම කියමි:

public class Something {

    public void justAnotherMethod() { ... }

}

new Thread(new Runnable() {
   public void run() {
    instanceOfSomething.justAnotherMethod();
   }
}).start();

මගේ මෑත කාලීන ජාවාස්ක්‍රිප්ට් සහ ඇක්ෂන්ස්ක්‍රිප්ට් 3 භාවිතය නිසා මෙය තරමක් බලපානු ඇත, නමුත් මේ ආකාරයෙන් ඔබේ පන්තියට එතරම් නොපැහැදිලි අතුරු මුහුණතක් ක්‍රියාත්මක කිරීමට අවශ්‍ය නොවේ Runnable.


38
මෙය ඇත්ත වශයෙන්ම තුන්වන ක්‍රමයක් නොවේ. ඔබ තවමත් ක්‍රියාත්මක කළ හැකි වන්නේ එය නිර්නාමිකව කිරීමෙනි.
දොන් රොබී

2
On ඩොන් රොබී: වෙනස්. එය බොහෝ විට පහසු වන අතර, ඔබට අඩංගු පන්ති / ක්‍රමයෙන් ක්ෂේත්‍ර සහ අවසාන දේශීය විචල්‍යයන් භාවිතා කළ හැකිය.
බාර්ට් වෑන් හියුකෙලොම්

6
ArBartvanHeukelom එය පහසු නමුත් වෙනස් නොවේ. ඔබට මෙය ඕනෑම වර්ගයක කැදැලි පන්තියක්, එනම් අභ්‍යන්තර පන්ති, දේශීය පන්ති සහ ලැම්බඩා ප්‍රකාශන සමඟ කළ හැකිය.
xehpuk

18

ජාවා 8 නිකුත් කිරීමත් සමඟ දැන් තුන්වන විකල්පය ඇත.

Runnableයනු ක්රියාකාරී අතුරු මුහුණත , එය අවස්ථා ලැම්ඩා ප්රකාශන හෝ ක්රමය යොමු නිර්මාණය කළ හැකි බව ඉන් අදහස් වන්නේ.

ඔබේ උදාහරණය ආදේශ කළ හැක්කේ:

new Thread(() -> { /* Code here */ }).start()

හෝ ඔබට ExecutorServiceක්‍රම සහ ක්‍රමවේදයක් භාවිතා කිරීමට අවශ්‍ය නම් :

executor.execute(runner::run)

මේවා ඔබගේ උදාහරණ වඩා පමණක් බොහෝ කෙටි නොවේ, පමණක් නොව, භාවිතා කිරීමේ වෙනත් පිළිතුරු සඳහන් වාසි බොහෝ සමඟ එන්න Runnableවැඩි Threadඑවැනි තනි වගකීමක් ලෙස, හා සංයුතිය භාවිතා ඔබ නූල් හැසිරීම විශේෂිත නැහැ නිසා. Runnableඔබේ උදාහරණ වලදී මෙන් ඔබට අවශ්‍ය වන්නේ නම් අමතර පන්තියක් නිර්මාණය කිරීමද මේ ආකාරයෙන් වළක්වයි .


මෙම පිළිතුර පැහැදිලි කිරීම අවශ්‍යයි. යම් ප්‍රහේලිකාවකට පසු, මම නිගමනය කරන්නේ () -> {}එය යමෙකුට අවශ්‍ය අභිරුචි තර්කනය නියෝජනය කළ යුතු බවයි? එබැවින් එය වඩා හොඳ යැයි () -> { /* Code here */ }කිව හැකිද?
මෙවලම් සාදන්නා

17

අතුරුමුහුණතක් ස්ථාපනය කිරීමෙන් ඔබේ කේතය සහ නූල් ක්‍රියාත්මක කිරීම අතර පිරිසිදු වෙන්වීමක් ලැබේ, එබැවින් මෙම අවස්ථාවේදී ධාවනය කළ හැකි ක්‍රියාත්මක කිරීමට මම කැමැත්තෙමි.


12

මෙහි සිටින සෑම කෙනෙකුම සිතන්නේ ධාවන පථය ක්‍රියාත්මක කිරීම යනු යා යුතු මාර්ගය වන අතර මම ඔවුන් සමඟ සැබවින්ම එකඟ නොවන නමුත් මගේ මතය අනුව ත්‍රෙඩ් එක දිගු කිරීම සඳහා නඩුවක් ද ඇත, ඇත්ත වශයෙන්ම ඔබ එය ඔබේ කේතයෙන් නිරූපණය කර ඇත.

ඔබ Runnable ක්‍රියාත්මක කරන්නේ නම් Runnable ක්‍රියාත්මක කරන පන්තියට නූල් නාමය පාලනය කළ නොහැක, එය නූල් නාමය සැකසිය හැකි ඇමතුම් කේතය වේ:

new Thread(myRunnable,"WhateverNameiFeelLike");

නමුත් ඔබ ත්‍රෙඩ් එක දිගු කළහොත් ඔබට මෙය පන්තිය තුළම කළමනාකරණය කර ගත හැකිය (ඔබේ උදාහරණයේ දී මෙන් ඔබ ත්‍රෙඩ් බී නූල නම් කරන්න). මෙම අවස්ථාවේදී ඔබ:

අ) නිදොස් කිරීමේ අරමුණු සඳහා එය වඩාත් ප්‍රයෝජනවත් නමක් ලබා දිය හැකිය

ආ) එම නම එම පංතියේ සියලුම අවස්ථාවන් සඳහා භාවිතා කිරීමට බල කරයි (ඔබ එය නූල් එකක් යන කාරණය නොසලකා හැර ඉහත සඳහන් දෑ ක්‍රියාත්මක කළ හැකි දෙයක් ලෙස කළහොත් මිස අපි මෙහි කතා කරන්නේ ඕනෑම අවස්ථාවක සම්මුතිය ගැන ය. මට දැනෙන එම හැකියාව නොසලකා හරින්න).

ඔබට නිදසුනක් ලෙස එය නිර්මාණය කිරීම පිළිබඳ හෝඩුවාවක් ගෙන එය නූල් නාමය ලෙස භාවිතා කළ හැකිය. මෙය අමුතු බවක් පෙනෙන්නට තිබුණත්, ඔබේ කේතය ව්‍යුහගත කර ඇති ආකාරය අනුව එය නිදොස්කරණය සඳහා ඉතා ප්‍රයෝජනවත් වේ.

මෙය කුඩා දෙයක් සේ පෙනුනද, ඔබ සතුව ඉතා සංකීර්ණ යෙදුමක් ඇති අතර, හදිසියේම දේවල් 'නැවතුණේ' (අවහිරතා හේතු නිසා හෝ ජාල ප්‍රොටෝකෝලයක ඇති අඩුපාඩුවක් නිසා විය හැකිය. පැහැදිලිව පෙනෙන - හෝ වෙනත් නිමක් නැති හේතු) ඉන්පසු සියලු නූල් 'Thread-1', 'Thread-2', 'Thread-3' ලෙස හඳුන්වන ජාවා වෙතින් තොගයක් ලබා ගැනීම සැමවිටම එතරම් ප්‍රයෝජනවත් නොවේ (එය ඔබගේ නූල් කෙසේද යන්න මත රඳා පවතී ව්‍යුහගතව ඇති අතර ඒවායේ තොග හෝඩුවාව අනුව ඔබට ප්‍රයෝජනවත් ලෙස පැවසිය හැකිද යන්න - ඔබ එකම කේතයක් ධාවනය කරන බහු නූල් කණ්ඩායම් භාවිතා කරන්නේ නම් සැමවිටම කළ නොහැක).

නූල් පංතියේ දිගුවක් නිර්මාණය කිරීමෙන් ඔබට එහි සාමාන්‍ය නමකින් එය කළ හැකි බව පවසා ඇති අතර, එහි නම එහි නිර්මාණ ඇමතුමේ සිරස් හෝඩුවාවක් ලෙස සකසා සම්මත ජාවා නූල් පන්තිය වෙනුවට ඔබේ ධාවනය කළ හැකි ක්‍රියාත්මක කිරීම් සමඟ භාවිතා කරන්න. (පහත බලන්න) නමුත් තොග හෝඩුවාවට අමතරව, නිදොස් කිරීම සඳහා නූල් නාමයෙන් ප්‍රයෝජනවත් වන තවත් සන්දර්භය විශේෂිත තොරතුරු තිබිය හැකිය (උදාහරණයක් ලෙස එය සැකසීමට හැකි බොහෝ පෝලිම් හෝ සොකට් වලින් එකක් ගැන සඳහනක් කළ හැකිය. එම අවස්ථාව සඳහා විශේෂයෙන් නූල් දිගු කරන්න, එවිට ඔබට (හෝ ඔබේ පුස්තකාල භාවිතා කරන වෙනත් අයට) නිශ්චිත තොරතුරු (උදා: පෝලිම් / සොකට්) නමින් භාවිතා කිරීම සඳහා සම්පාදක බලයක් ලබා ගත හැකිය.

මෙන්න සාමාන්‍ය නූලට එහි නම ලෙස ඇමතුම් තොග හෝඩුවාවක් ඇත:

public class DebuggableThread extends Thread {
    private static String getStackTrace(String name) {
        Throwable t= new Throwable("DebuggableThread-"+name);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(os);
        t.printStackTrace(ps);
        return os.toString();
    }

    public DebuggableThread(String name) {
        super(getStackTrace(name));
    }

    public static void main(String[] args) throws Exception {
        System.out.println(new Thread());
        System.out.println(new DebuggableThread("MainTest"));
    }
}

මෙහි නම් දෙක සංසන්දනය කරමින් ප්‍රතිදානයේ නියැදියක් ඇත:

Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
    at DebuggableThread.getStackTrace(DebuggableThread.java:6)
    at DebuggableThread.<init>(DebuggableThread.java:14)
    at DebuggableThread.main(DebuggableThread.java:19)
,5,main]

cHao ඔබේ අදහස කුමක්ද? නූල් නිර්මාණය කිරීමේදී ඔබට ඔබේ කේතය භාවිතා කළ නොහැකි විය (ඒ වෙනුවට ඔබට සරල නමක් ලැබෙනු ඇත හෝ නූල් දියත් කිරීමේ ස්ටැක්ට්‍රේස් එකක් ලැබෙනු ඇත) නමුත් නූල් උප වර්ගීකරණය කිරීමෙන් ඔබට එය හරියටම කළ හැකිය. එය, තව දුරටත් සන්දර්භය තුළ විශේෂිත තොරතුරු අවශ්‍ය වන අතර එමඟින් ගැටළුවක් ඇති විය හැකි නූල් පිළිබඳව වඩාත් ස්ථිර අවබෝධයක් ලබා දේ.
ඇන්ටනි එම්

8
මගේ අදහස නම්, “ඔබ ධාවනය කළ හැකි දේ ක්‍රියාත්මක කරන්නේ නම්, ධාවනය කළ හැකි ක්‍රියාවට නංවන පන්තියට නූල් නාමය පාලනය කළ නොහැක ...” යනු අසත්‍යයකි. පංතිය ක්‍රියාත්මක කරන විට Runnableඇත්ත වශයෙන්ම නූල් නාමය පාලනය කළ හැකිය, මන්ද කේතය ධාවනය කරන නූල් අර්ථ දැක්වීම අනුව වත්මන් නූල් වේ (සහ ආරක්ෂක චෙක්පත් පසු කරන ඕනෑම කේතයකට නූල් නම් පාලනය කළ හැකිය). ඔබගේ තනතුරෙන් අඩක් "ඔම්ග්, නූල් නම් ගැන කුමක් කිව හැකිද!"
cHao

නූල් නම? නූල් පංතිය දීර් ing කිරීමද ඔබව වළක්වන්නේ නැත.
රිචීඑච්

11

ධාවනය කළ හැකි නිසා:

  • වෙනත් පන්තියක් දීර් extend කිරීම සඳහා ධාවනය කළ හැකි ක්‍රියාත්මක කිරීම සඳහා වඩාත් නම්‍යශීලී බවක් ලබා දේ
  • කේතය ක්‍රියාත්මක කිරීමෙන් වෙන් කරයි
  • ඔබේ ධාවන පථය නූල් තටාකයකින්, සිදුවීම් නූලකින් හෝ අනාගතයේදී වෙනත් ආකාරයකින් ධාවනය කිරීමට ඔබට ඉඩ දෙයි.

ඔබට මේ කිසිවක් දැන් අවශ්‍ය නොවුවද, ඔබට අනාගතයේදී විය හැකිය. නූල් අභිබවා යාමෙන් කිසිදු ප්‍රතිලාභයක් නොමැති බැවින්, ධාවනය කළ හැකි වඩා හොඳ විසඳුමකි.


11

මෙය ඉතා ජනප්‍රිය මාතෘකාවක් වන අතර හොඳ පිළිතුරු සෑම තැනකම පැතිරී ඇති අතර ඉතා ගැඹුරින් කටයුතු කරන බැවින් අනෙක් අයගේ හොඳ පිළිතුරු වඩාත් සංක්ෂිප්ත ස්වරූපයකට සම්පාදනය කිරීම යුක්ති සහගත යැයි මට හැඟුණි, එබැවින් නවකයන්ට පහසු දළ විශ්ලේෂණයක් පෙරට ගෙන යා හැකිය:

  1. ක්‍රියාකාරීත්වය එක් කිරීමට හෝ වෙනස් කිරීමට ඔබ සාමාන්‍යයෙන් පන්තියක් දිගු කරයි. ඒ නිසා, ඔබ කැමති නැති නම් කිරීමට නැවත ලියවෙනු ඕනෑම විෂයය හැසිරීම , එසේ නම් Runnable භාවිතා කරන්න.

  2. එකම ආලෝකයකින්, ඔබට නූල් ක්‍රම උරුම කර ගැනීමට අවශ්‍ය නොවන්නේ නම් , ධාවනය කළ හැකි භාවිතා කිරීමෙන් ඔබට එම පොදු කාර්ය නොමැතිව කළ හැකිය .

  3. තනි උරුමය : ඔබ නූල් දිගු කළහොත් ඔබට වෙනත් පන්තියකින් විහිදිය නොහැක, එබැවින් ඔබ කළ යුත්තේ එය නම්, ඔබ ධාවනය කළ හැකි භාවිතා කළ යුතුය.

  4. එය ඒ ආකාරයෙන්ම එය Runnable තිබිය වඩා හොඳ වන අතර, තාක්ෂණික ක්රම වලින් වෙන් වසම තර්කයට හොඳ නිර්මාණ අන් අයගෙන් වෙන්ව ඔබේ වෙතින් කාර්යය ඔබගේ අනුශූරතාවය .

  5. ඔබට එකම ධාවනය කළ හැකි වස්තුව කිහිප වතාවක් ක්‍රියාත්මක කළ හැකිය , කෙසේ වෙතත්, නූල් වස්තුවක් ආරම්භ කළ හැක්කේ එක් වරක් පමණි. (සමහර විට හේතුව, ක්‍රියාත්මක කරන්නන් ධාවනය කළ හැකි දේ පිළිගන්නේ, නමුත් නූල් නොවේ.)

  6. ඔබ ඔබේ කාර්යය ධාවනය කළ හැකි ලෙස සංවර්ධනය කරන්නේ නම්, දැන් සහ අනාගතයේදී එය භාවිතා කරන්නේ කෙසේද යන්න ඔබට සියලු නම්‍යශීලී බවක් ඇත. ඔබට එය ක්‍රියාත්මක කරන්නන් හරහා පමණක් නොව නූල් හරහා ද ක්‍රියාත්මක කළ හැකිය. වෙනත් සාමාන්‍ය වර්ගයක් / වස්තුවක් මෙන් එකම නූල් තුළම ඔබට එය එකවර භාවිතා කළ හැකිය.

  7. මෙය ඔබගේ ඒකක පරීක්ෂණ වලදී කාර්ය-තර්කනය සහ සමගාමී කොටස් වෙන් කිරීමද පහසු කරයි .

  8. ඔබ මෙම ප්‍රශ්නය ගැන උනන්දුවක් දක්වන්නේ නම් , කැල්බල් සහ ධාවනය කළ හැකි අතර වෙනස ගැන ඔබ උනන්දු වනු ඇත .


In පිනෝ ඔව්, නූල් ද ධාවනය කළ හැකි ය. කෙසේ වෙතත්, ඔබ එය ධාවනය කළ හැකි එකක් ලෙස භාවිතා කිරීම සඳහා එය දිගු කළහොත්, එයින් ඇති ප්‍රයෝජනය කුමක්ද? සියලු ගමන් මලු නොමැතිව සරල ධාවනය කළ හැකි භාවිතා නොකරන්නේ ඇයි? ඉතින්, මම තර්ක කරමි, ඔබ නූල් දිගු කළහොත්, ඔබ ද එහි ආරම්භක ක්‍රමය භාවිතා කර එය ක්‍රියාත්මක කරනු ඇත, එය එක් වරක් පමණක් භාවිතා කළ හැකිය. නිධිෂ්-ක්‍රිෂ්ණන්ට ඔහුගේ පිළිතුරෙහි සඳහන් කිරීමට අවශ්‍ය වූයේ එයයි. සටහන, එය මගේ වෙනත් පිළිතුරු සම්පාදනය කිරීම හෝ කෙටි සාරාංශයක් පමණක් බව සලකන්න.
ජෝර්ග්


8

ඔරකල්ගේ නූල් නිබන්ධනය නිර්වචනය කිරීම සහ ආරම්භ කිරීම පිළිබඳව මෙය සාකච්ඡා කෙරේ :

ඔබ භාවිතා කළ යුත්තේ කුමන මෝඩයන්ද? ධාවනය කළ හැකි වස්තුවක් භාවිතා කරන පළමු මෝඩය වඩාත් සාමාන්‍ය ය, මන්ද ධාවනය කළ හැකි වස්තුවට නූල් හැර වෙනත් පන්තියක් උපවර්ග කළ හැකි බැවිනි. දෙවන මෝඩකම සරල යෙදුම්වල භාවිතා කිරීම පහසුය, නමුත් ඔබේ කාර්ය පන්තිය නූල් වලින් පැවත එන්නෙකු විය යුතුය. මෙම පාඩම අවධානය යොමු කරන්නේ පළමු ප්‍රවේශය මත වන අතර එය ක්‍රියාත්මක කළ හැකි කාර්යය ත්‍රෙඩ් වස්තුවෙන් වෙන් කරයි. මෙම ප්‍රවේශය වඩාත් නම්‍යශීලී වනවා පමණක් නොව, පසුව ආවරණය වන ඉහළ මට්ටමේ නූල් කළමනාකරණ API සඳහාද එය අදාළ වේ.

වෙනත් වචන වලින් කිවහොත්, Runnableඔබේ පන්තිය හැර වෙනත් පන්තියක් විහිදෙන අවස්ථා වලදී ක්‍රියාත්මක කිරීම ක්‍රියාත්මක වේ Thread. ජාවා බහු උරුමයට සහාය නොදක්වයි. එසේම, Threadසමහර ඉහළ මට්ටමේ නූල් කළමනාකරණ API භාවිතා කරන විට දීර් ing කිරීම කළ නොහැක. දිගු Threadකිරීම වඩාත් සුදුසු එකම අවස්ථාව වන්නේ අනාගතයේ යාවත්කාලීන කිරීම් වලට යටත් නොවන කුඩා යෙදුමකි. Runnableඔබේ ව්‍යාපෘතිය වර්ධනය වන විට එය වඩාත් නම්‍යශීලී බැවින් එය ක්‍රියාත්මක කිරීම සැමවිටම හොඳය . ඔබට ජාවා හි බොහෝ අතුරුමුහුණත් ක්‍රියාත්මක කළ හැකි බැවින් නිර්මාණ වෙනසක් විශාල බලපෑමක් ඇති නොකරනු ඇත, නමුත් එක් පන්තියක් පමණක් දිගු කරන්න.


8

සරලම පැහැදිලි කිරීම වනුයේ ක්‍රියාත්මක කිරීමෙන් Runnableඅපට එකම වස්තුව බහු නූල් වලට පැවරිය හැකි අතර සෑම එකක්ම Threadඑකම වස්තු තත්වයන් සහ හැසිරීම බෙදා ගනී.

උදාහරණයක් ලෙස, දෙකක් නූල් ඇත සිතමු thread1 තබන යනු පූර්ණ සංඛ්යාවකි මාලාවක් සහ thread2 අරාව පුරවන විට අරාව සිට පූර්ණ සංඛ්යා ගනී. සඳහා පිණිස බව දැනුම් thread2 වැඩ කිරීමට එය ද යන්න, අරාව රාජ්ය දැන ගැනීමට අවශ්ය thread1 එය පිරී හෝ නැත.

ක්‍රියාත්මක කිරීම Runnableමඟින් ඔබට වස්තුව බෙදා ගැනීමට මෙම නම්‍යශීලී බවක් ලබා ගත හැකි අතර extends Threadසෑම නූල් සඳහාම නව වස්තු නිර්මාණය කිරීමට ඔබව පොළඹවයි. එබැවින් නූල් 1 මඟින් කරන ඕනෑම යාවත්කාලීන කිරීමක් නූල් 2 වෙත අහිමි වේ.


7

මම වැරදි නොවේ නම්, එය අඩු හෝ වැඩි වශයෙන් සමාන වේ

අතුරු මුහුණතක් සහ වියුක්ත පන්තියක් අතර වෙනස කුමක්ද?

දිගු කිරීම " Is A " සම්බන්ධතාවයක් සහ අතුරු මුහුණතක් " has " හැකියාවක් සපයයි .

ක්‍රියාත්මක කිරීමට කැමති මනාප :

  1. ඔබට Thread පන්තිය දීර් extend කිරීමට අවශ්‍ය නැතිනම් Thread API පෙරනිමි ක්‍රියාත්මක කිරීම වෙනස් කළ යුතුය
  2. ඔබ ගින්නක් ක්‍රියාත්මක කරන්නේ නම් සහ විධානය අමතක කරන්න
  3. ඔබ දැනටමත් වෙනත් පන්තියක් දීර් If කරන්නේ නම්

" නූල් දිගු කරයි " යන්න කැමති :

  1. ඔරකල් ප්‍රලේඛන පිටුවෙහි ලැයිස්තුගත කර ඇති පරිදි ඔබට මෙම නූල් ක්‍රම කිසිවක් අභිබවා යාමට සිදුවුවහොත්

සාමාන්‍යයෙන් ඔබට නූල් හැසිරීම ඉක්මවා යාමට අවශ්‍ය නොවේ. එබැවින් ධාවනය කළ හැකි දෑ ක්‍රියාත්මක කරයි ගොඩක් වෙලාවට ඉදිරිපත් කර ඇත.

වෙනත් සටහනක, උසස් ExecutorServiceහෝ ThreadPoolExecutorServiceඒපීඅයි භාවිතා කිරීම වඩාත් නම්‍යශීලී බවක් සහ පාලනයක් සපයයි.

මෙම SE ප්‍රශ්නය දෙස බලන්න:

ක්‍රියාත්මක කරන්නාගේ සේවය එදිරිව අනියම් නූල් ස්පෝනර්


5

ධාවනය කළ හැකි ක්‍රියාවට නැංවීමෙන් නූල් පන්තිය වෙන් කිරීමෙන් නූල් සහ ධාවන () ක්‍රමය අතර ඇති විය හැකි සමමුහුර්තකරණ ගැටළු මඟහරවා ගත හැකිය. වෙනම ධාවනය කළ හැකි සාමාන්‍යයෙන් ධාවනය කළ හැකි කේතය යොමු කර ක්‍රියාත්මක කරන ආකාරයට වැඩි නම්යතාවයක් ලබා දෙයි.


5

ඒ තියෙන්නේ එස්ඝන තනි වගකීම:.

නූල් මූර්තිමත් ධාවනය සන්දර්භය පිළිබඳ: (අඩුක්කුව රාමුව, නූල් අංකය, ආදිය ක්රියාත්මක සන්දර්භය තුල මෙන්) අසමමිතික ක්රියාත්මක කේතය කැබැල්ලක්. එම කේත කොටස සමමුහුර්ත හෝ අසමමුහුර්ත වේවා එකම ක්‍රියාත්මක කිරීම විය යුතුය .

එක් ක්‍රියාවට නැංවීමේදී ඔබ ඒවා එකට එකතු කරන්නේ නම්, එහි ප්‍රති ing ලයක් ලෙස ඇති වස්තුව වෙනස් වීමට සම්බන්ධ නොවන හේතු දෙකක් ලබා දෙයි :

  1. ඔබගේ යෙදුමේ නූල් හැසිරවීම (එනම් ක්‍රියාත්මක කිරීමේ සන්දර්භය විමසීම සහ වෙනස් කිරීම)
  2. කේත කොටස මඟින් ක්‍රියාත්මක කරන ඇල්ගොරිතම (ධාවනය කළ හැකි කොටස)

ඔබ භාවිතා කරන භාෂාව අර්ධ පංති හෝ බහු උරුමයන් සඳහා සහය දක්වන්නේ නම්, එවිට ඔබට එක් එක් හේතුව එහි සුපිරි පන්තියෙන් වෙන් කළ හැකිය, නමුත් ඒවායේ අංග කට්ටල අතිච්ඡාදනය නොවන බැවින් එය වස්තු දෙක රචනා කිරීමට සමාන වේ. එය න්‍යාය සඳහා ය.

ප්‍රායෝගිකව, පොදුවේ ගත් කල, වැඩසටහනකට අවශ්‍ය ප්‍රමාණයට වඩා සංකීර්ණත්වයක් ගෙනයාමට අවශ්‍ය නොවේ. නිශ්චිත කර්තව්‍යයක් සඳහා එක් නූල් වැඩ කරන්නේ නම්, එම කාර්යය කිසි විටෙකත් වෙනස් නොකර, කාර්යයන් වෙනම පන්ති බවට පත්කිරීමේ තේරුමක් නැති අතර ඔබේ කේතය සරල ලෙස පවතී.

ජාවා සන්දර්භය තුළ , පහසුකම දැනටමත් ඇති බැවින් , තනිවම තනිවම Runnableපන්ති සමඟ කෙලින්ම ආරම්භ කිරීම පහසු වන අතර , ඔවුන්ගේ අවස්ථා Thread(හෝ Executor) අවස්ථාවන්ට යොමු කරන්න. එම රටාවට පුරුදු වූ පසු , සරල ධාවනය කළ හැකි නූල් නඩුවට වඩා භාවිතා කිරීම (හෝ කියවීම පවා) අපහසු නැත.


5

මූලික පංතියක් දීර් than කරනවාට වඩා අතුරු මුහුණතක් ක්‍රියාත්මක කිරීමට ඔබට අවශ්‍ය එක් හේතුවක් නම් ඔබ දැනටමත් වෙනත් පන්තියක් දීර් ing කිරීමයි. ඔබට එක් පන්තියක් පමණක් දිගු කළ හැකි නමුත් ඔබට ඕනෑම අතුරු මුහුණතක් ක්‍රියාත්මක කළ හැකිය.

ඔබ නූල් දිගු කරන්නේ නම්, ඔබ මූලික වශයෙන් ඔබේ තර්කනය 'මෙය' හැර වෙනත් ත්‍රෙඩ් එකකින් ක්‍රියාත්මක කිරීම වළක්වයි. ඔබේ තර්කනය ක්‍රියාත්මක කිරීම සඳහා ඔබට අවශ්‍ය වන්නේ නූල් කිහිපයක් නම් , ධාවනය කළ හැකි ක්‍රියාත්මක කිරීම වඩා හොඳය.


ඔව්, ඕනෑම පන්තියක් දීර් ing කිරීමෙන් ඔබේම තර්කනය ක්‍රියාත්මක කිරීමට නිදහස ඇති පරිදි ධාවනය කළ හැකි අතුරුමුහුණත ක්‍රියාත්මක කිරීමෙන්, ත්‍රෙඩ් පන්තියට වඩා ධාවනය කළ හැකි දේ වඩාත් කැමති වන්නේ එබැවිනි.
ආකාෂ් 5288

5

ඔබ ධාවනය කළ හැකි භාවිතා කරන්නේ නම්, ඔබේ වෙනත් ඕනෑම පන්තියකට ව්‍යාප්ත කිරීමට ඉඩ ඉතිරි කර ගත හැකිය.


5

අපගේ පංතිය a ලෙස හැසිරීමට අවශ්‍ය මූලික හේතුව නැවත බැලීමට අපට හැකිද? Thread ? කිසිසේත් හේතුවක් නැත, අපට අවශ්‍ය වූයේ කාර්යයක් ක්‍රියාත්මක කිරීමට ය, බොහෝ දුරට අසමමුහුර්ත ආකාරයකින් ය, එයින් හරියටම අදහස් කරන්නේ කාර්යය ක්‍රියාත්මක කිරීම අපගේ ප්‍රධාන නූලෙන් සහ ප්‍රධාන නූලෙන් අතු බෙදිය යුතු බවයි. අතු මාර්ගය සඳහා (කාර්යය).

මෙය සම්පූර්ණ අරමුණ නම්, විශේෂිත නූල් එකක අවශ්‍යතාවය මා දකින්නේ කොතැනින්ද? පද්ධතියේ නූල් තටාකයෙන් RAW නූල් එකක් ගෙන එය අපගේ කාර්යය පැවරීමෙන් (අපගේ පන්තියේ උදාහරණයක් විය හැකිය) මෙය කළ හැකිය.

එබැවින් අපි OOPs සංකල්පයට අවනත වී අපට අවශ්‍ය වර්ගයේ පන්තියක් ලියමු. දේවල් කිරීමට බොහෝ ක්‍රම තිබේ, එය නිවැරදි ආකාරයෙන් කිරීම වැදගත් වේ.

අපට කාර්යයක් අවශ්‍යයි, එබැවින් ත්‍රෙඩ් එකක ධාවනය කළ හැකි කාර්ය නිර්වචනයක් ලියන්න. එබැවින් ධාවනය කළ හැකි භාවිතා කරන්න.

සැමවිටම මතක තබා ගන්න implementsහැසිරීමක් ලබා දීමට විශේෂයෙන් භාවිතා කරයිextends එය අංගයක් / දේපලක් ලබා දීමට භාවිතා කරයි.

අපට නූල් වල දේපල අවශ්‍ය නැත, ඒ වෙනුවට අපට අවශ්‍ය වන්නේ අපගේ පන්තිය ක්‍රියාත්මක කළ හැකි කාර්යයක් ලෙස හැසිරීමයි.


4

ඔව්, ඔබ ThreadA ඇමතුම අමතන්නේ නම්, ආරම්භක ක්‍රමය ඇමතීමට අවශ්‍ය නොවන අතර ක්‍රියාත්මක කිරීමේ ක්‍රමය වන්නේ ThreadA පන්තියට ඇමතුමෙන් පසුව පමණි. නමුත් ThreadB ඇමතුම භාවිතා කරන්නේ නම් ඇමතුම් ධාවනය කිරීමේ ක්‍රමය සඳහා ආරම්භක නූල් අවශ්‍ය වේ. ඔබට තවත් උදව් තිබේ නම්, මට පිළිතුරු දෙන්න.


4

සඳහන් කර ඇති සියලු හේතුන් සඳහා Runnable භාවිතා කිරීම වඩාත් ප්‍රයෝජනවත් බව මට පෙනේ, නමුත් සමහර විට මම Thread දිගු කිරීමට කැමතියි එවිට මට මගේම නූල් නැවැත්වීමේ ක්‍රමයක් නිර්මාණය කර එය මා විසින් නිර්මාණය කරන ලද නූල් මත කෙලින්ම අමතන්න.


4

ජාවා බහු උරුමයට සහය නොදක්වන බැවින් ඔබ නූල් පන්තිය දීර් if කරන්නේ නම් වෙනත් කිසිදු පන්තියක් දීර් will නොවේ.

උදාහරණ සඳහා: ඔබ ඇප්ලෙට් එකක් නිර්මාණය කරන්නේ නම් එය ඇප්ලට් පංතිය දීර් extend කළ යුතුය. එබැවින් මෙහි නූල් සෑදිය හැකි එකම ක්‍රමය වන්නේ ධාවනය කළ හැකි අතුරු මුහුණත ක්‍රියාත්මක කිරීමයි


4

Runnableඅතර, අතුරු මුහුණතක් වේ Threadමෙම අතුරුමුහුණත ක්රියාත්මක වන පන්තිය යි. සැලසුම් දෘෂ්ටි කෝණයකින්, කර්තව්‍යයක් නිර්වචනය කරන ආකාරය සහ එය ක්‍රියාත්මක කරන ආකාරය අතර පිරිසිදු වෙන්වීමක් තිබිය යුතුය. පළමුවැන්න ක්‍රියාත්මක කිරීමේ වගකීම වන Runnalbeඅතර දෙවැන්න Threadපන්තියේ රැකියාවයි . බොහෝ අවස්ථාවන්හීදී ක්‍රියාත්මක Runnableකිරීම නිවැරදි ක්‍රමයයි.


4

නූල් සහ ධාවනය කළ හැකි අතර වෙනස .අපි නූල් පන්තිය භාවිතයෙන් නූල් නිර්මාණය කරන්නේ නම්, අප විසින් නිර්මාණය කරන ලද වස්තු සංඛ්‍යාවට සමාන නූල් ගණන. ධාවනය කළ හැකි අතුරුමුහුණත ක්‍රියාත්මක කිරීමෙන් අපි නූල් නිර්මාණය කරන්නේ නම් අපට බහු නූල් සෑදීම සඳහා තනි වස්තුවක් භාවිතා කළ හැකිය. එබැවින් තනි වස්තුවක් බහු නූල් මගින් බෙදා ගනී. එබැවින් එය අඩු මතකයක් ගනී

එබැවින් අපගේ දත්ත සංවේදී නොවේ නම් අවශ්‍යතාවය මත පදනම්ව. එබැවින් එය අපට ධාවනය කළ හැකි අතුරුමුහුණත භාවිතා කළ හැකි බහු නූල් අතර බෙදා ගත හැකිය.


4

මගේ ශත දෙක මෙහි එකතු කිරීම - හැකි සෑම විටම භාවිතා කරන්න implements Runnable. පහත දැක්වෙන්නේ ඔබ extends Threads භාවිතා නොකළ යුත්තේ ඇයිද යන්න පිළිබඳ අවවාද දෙකක්

  1. ඉතා මැනවින් ඔබ කිසි විටෙකත් නූල් පන්තිය දීර් extend නොකළ යුතුය. මෙම Threadපන්ති කළ යුතු final. අවම වශයෙන් එහි ක්රම වැනි thread.getId(). විස්තාරණය කිරීම හා සම්බන්ධ දෝෂයක් සඳහා මෙම සාකච්ඡාව බලන්න Thread.

  2. ප්‍රහේලිකා නිරාකරණය කිරීමට කැමති අයට නූල් දිගු කිරීමේ තවත් අතුරු ආබාධයක් දැකිය හැකිය. කිසිවෙකු විසින් දැනුම් නොදෙන විට පහත කේතය වෙත ළඟා විය නොහැකි කේතය මුද්‍රණය වේ.

කරුණාකර http://pastebin.com/BjKNNs2G බලන්න .

public class WaitPuzzle {

    public static void main(String[] args) throws InterruptedException {
        DoNothing doNothing = new DoNothing();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        Thread.sleep(100);
        doNothing.start();
        while(true) {
            Thread.sleep(10);
        }
    }


    static class WaitForever extends  Thread {

        private DoNothing doNothing;

        public WaitForever(DoNothing doNothing) {
            this.doNothing =  doNothing;
        }

        @Override
        public void run() {
            synchronized (doNothing) {
                try {
                    doNothing.wait(); // will wait forever here as nobody notifies here
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Unreachable Code");
            }
        }
    }

    static class DoNothing extends Thread {

        @Override
        public void run() {
            System.out.println("Do Nothing ");
        }
    } 
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.