2

I'm reading J. Bloch's effective java and now I'm at the section about executors. He said that we should prefer using executors to directly usage of Threads. As far as I got the primary reason for that is

The key abstraction is no longer Thread , which served as both the unit of work and the mechanism for executing it. Now the unit of work and mechanism are separate. The key abstraction is the unit of work, which is called a task.

It's not quite clear what the unit of work means here. I tried to search for it and found that there's a design pattern related to db-operation. But how does it tie with Threads? Or there is another interpretation of this pattern?

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • Maybe this answer: http://stackoverflow.com/a/17347259/180100 –  Nov 13 '15 at 06:29
  • 1
    Unit of work describes group of operations that is executed in some thread or even different process. Unit of work are dirty dishes, to be cleaned and you can wash them in many different places. – pcejrowski Nov 13 '15 at 06:32

3 Answers3

4

It's purposefully nebulous: it's just "a thing you want done," and the more precise meaning is up to you.

If you want to download a file, that's a unit of work. If you want to compute a hash of some big chuck of data, that's a unit of work. If you want to draw something on the screen, that's a unit of work.

What this blurb is getting at is that this unit of work used to be tied directly to a Java thread (via the Thread class), which is in turn tied relatively directly to the OS's threads (some hand-waving there :) ). A more modern approach is to define the work as a task, and then give a bunch of tasks to a Thread whose life cycle is longer than any of those tasks. That thread then executes those tasks. This lets you more explicitly manage Thread resources, which are relatively heavyweight.

A rough analogy would be to hire a new employee for every task you want done (write this spec, or make some coffee, or fix this bug) vs hiring just a few employees and giving them small tasks as needed.

yshavit
  • 42,327
  • 7
  • 87
  • 124
  • 1
    One name for this idea is "Separation of concerns". Each object should represent just one thing: A naked Thread represents the capacity to do work. An object derived from Thread with a specialized run() method probably represents both the capacity to do work _and_ the unit of work to be done. – Solomon Slow Nov 13 '15 at 12:06
1

This question is similar to this SO post (q.v. Jon Skeet's highly upvoted answer), but I will give an answer anyway. There are two ways to create a thread in Java. The first way is to extend the Thread class directly, and the second is to implement the Runnable interface. These two options are what Bloch is generally arguing over.

If you choose to extend the Thread class directly, then you are not free to extend any other class (since Java does not allow multiple inheritance). This is a design limitation. On the other hand, if you implement the marker interface Runnable, then you are still free to extend any other class you wish.

Philosophically, using the interface is generally considered better design, because it simply marks a class a something which can be run as a thread, without explicitly saying how it will be run.

Community
  • 1
  • 1
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
1

The simplest (and so not quite correct) approach is to understand the unit of work as execution of a method (procedure, function). Anyway, unit of work is always represented as a method.

Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38