Difference between revisions of "Programming in D for Java Programmers"

From D Wiki
Jump to: navigation, search
(Difference between Java's static member variables and D's)
Line 13: Line 13:
 
}</syntaxhighlight>
 
}</syntaxhighlight>
  
 +
== Static Class Member Variables ==
 +
 +
In Java if you declare a member variable as <code>static</code> it will be stored in global storage for the entire program, allowing you to access the same reference from multiple threads.
 +
 +
<syntaxhighlight lang="Java">
 +
class Person {
 +
  public String firstName;
 +
 +
  public Person(String fname) {
 +
      this.firstName = fname;
 +
  }
 +
}
 +
 +
class ProgramState {
 +
  public static Person person;
 +
 +
  static {
 +
      person = new Person("Jessie");
 +
  }
 +
}
 +
 +
public class Program {
 +
 +
  public static void main(String[] args) throws Exception {
 +
      new ProgramState();
 +
      Thread secondThread = new Thread(new Runnable() {
 +
        @Override
 +
        public void run() {
 +
            ProgramState.person.firstName = "James";
 +
        }
 +
      });
 +
      System.out.println(ProgramState.person.firstName); // => Jessie
 +
      secondThread.start();
 +
      secondThread.join();
 +
      System.out.println(ProgramState.person.firstName); // => James
 +
  }
 +
}</syntaxhighlight>
 +
 +
A <code>static</code> member variable in D is local to the ''current thread only'', known as thread-local storage. Every thread you create will have a different version of your <code>static</code> member variables.
 +
To have the same behaviour as Java in D, you need to use the <code>__gshared</code> type qualifier.
 +
 +
<syntaxhighlight lang="D">import core.thread;
 +
 +
class Person
 +
{
 +
  string firstName;
 +
 +
  this(string fname) {
 +
      firstName = fname;
 +
  }
 +
}
 +
 +
class ProgramState
 +
{
 +
  __gshared static Person person;
 +
 +
  static this()
 +
  {
 +
      person = new Person("Jessie");
 +
  }
 +
}
 +
 +
void main()
 +
{
 +
  new ProgramState();
 +
  Thread secondThread = new Thread(() {
 +
      ProgramState.person.firstName = "James";
 +
  });
 +
  assert("Jessie" == ProgramState.person.firstName);
 +
  secondThread.start();
 +
  secondThread.join();
 +
  assert("James" == ProgramState.person.firstName, "firstName is not James");
 +
}</syntaxhighlight>
 +
 +
Removing the <code>__gshared</code> from the above snippet will result in the second assertion failing as <code>ProgramState.person.firstName</code> will be <code>"Jessie"</code>.
 +
 +
For an overview of the different forms of concurrency, see the [https://ddili.org/ders/d.en/concurrency_shared.html Data Sharing Concurrency] chapter in ''Programming in D'' which also explains one of D's preferred way of sharing variables between threads: <code>shared</code>.
 
[[Category:Languages versus D]]
 
[[Category:Languages versus D]]

Revision as of 10:06, 26 August 2023

Downcasting

The Java way

if (animal instanceof Cat)
{
    Cat cat = (Cat) animal;
    /* use cat */
}

The D way

if(auto cat = cast(Cat) animal)
{
    /* use cat */
}

Static Class Member Variables

In Java if you declare a member variable as static it will be stored in global storage for the entire program, allowing you to access the same reference from multiple threads.

class Person {
   public String firstName;

   public Person(String fname) {
      this.firstName = fname;
   }
}

class ProgramState {
   public static Person person;

   static {
      person = new Person("Jessie");
   }
}

public class Program {

   public static void main(String[] args) throws Exception {
      new ProgramState();
      Thread secondThread = new Thread(new Runnable() {
         @Override
         public void run() {
            ProgramState.person.firstName = "James";
         }
      });
      System.out.println(ProgramState.person.firstName); // => Jessie
      secondThread.start();
      secondThread.join();
      System.out.println(ProgramState.person.firstName); // => James
   }
}

A static member variable in D is local to the current thread only, known as thread-local storage. Every thread you create will have a different version of your static member variables. To have the same behaviour as Java in D, you need to use the __gshared type qualifier.

import core.thread;

class Person
{
   string firstName;

   this(string fname) {
      firstName = fname;
   }
}

class ProgramState
{
   __gshared static Person person;

   static this()
   {
      person = new Person("Jessie");
   }
}

void main()
{
   new ProgramState();
   Thread secondThread = new Thread(() {
      ProgramState.person.firstName = "James";
   });
   assert("Jessie" == ProgramState.person.firstName);
   secondThread.start();
   secondThread.join();
   assert("James" == ProgramState.person.firstName, "firstName is not James");
}

Removing the __gshared from the above snippet will result in the second assertion failing as ProgramState.person.firstName will be "Jessie".

For an overview of the different forms of concurrency, see the Data Sharing Concurrency chapter in Programming in D which also explains one of D's preferred way of sharing variables between threads: shared.