If you have to develop a program that runs a lot of concurrent tasks, this approach has the following disadvantages:
You create a Thread object per task. If you have to execute a big number of tasks, this can affect the throughput of the application.
You have to control and manage efficiently the resources of the computer.If you create too many threads, you can saturate the system.
Since Java 5, the Java concurrency API provides a mechanism that aims at resolving problems. This mechanism is called the Executor framework and is around the Executor interface, its subinterface ExecutorService , and the ThreadPoolExecutor class that implements both interfaces.
This mechanism separates the task creation and its execution. With an executor, you only have to implement the Runnable objects and send them to the executor. It is responsible for their execution, instantiation, and running with necessary threads. But it goes beyond that and improves performance using a pool of threads. When you send a task to the executor, it tries to use a pooled thread for the execution of this task, to avoid continuous spawning of threads. Another important advantage of the Executor framework is the Callable interface. It's similar to the Runnable interface, but offers two improvements, which are as follows:
The main method of this interface, named call() , may return a result.
When you send a Callable object to an executor, you get an object that implements the Future interface. You can use this object to control the status and the result of the Callable object.
/**
* Main class of the example. Creates a server and 100 request of the Task class
* that sends to the server
*
*/
public class Main {
/**
* Main method of the example
* @param args
*/
public static void main(String[] args) {
// Create the server
Server server=new Server();
// Send 100 request to the server and finish
for (int i=0; i<100; i++){
Task task=new Task("Task "+i);
server.executeTask(task);
}
server.endServer();
}
}
/**
* This class simulates a server, for example, a web server, that receives
* requests and uses a ThreadPoolExecutor to execute those requests
*
*/
public class Server {
/**
* ThreadPoolExecutors to manage the execution of the request
*/
private ThreadPoolExecutor executor;
/**
* Constructor of the class. Creates the executor object
*/
public Server(){
executor=(ThreadPoolExecutor)Executors.newCachedThreadPool();
}
/**
* This method is called when a request to the server is made. The
* server uses the executor to execute the request that it receives
* @param task The request made to the server
*/
public void executeTask(Task task){
System.out.printf("Server: A new task has arrived\n");
executor.execute(task);
System.out.printf("Server: Pool Size: %d\n",executor.getPoolSize());
System.out.printf("Server: Active Count: %d\n",executor.getActiveCount());
System.out.printf("Server: Completed Tasks: %d\n",executor.getCompletedTaskCount());
}
/**
* This method shuts down the executor
*/
public void endServer() {
executor.shutdown();
}
}
/**
* This class implements a concurrent task
*
*/
public class Task implements Runnable {
/**
* The start date of the task
*/
private Date initDate;
/**
* The name of the task
*/
private String name;
/**
* Constructor of the class. Initializes the name of the task
* @param name name asigned to the task
*/
public Task(String name){
initDate=new Date();
this.name=name;
}
/**
* This method implements the execution of the task. Waits a random period of time and finish
*/
@Override
public void run() {
System.out.printf("%s: Task %s: Created on: %s\n",Thread.currentThread().getName(),name,initDate);
System.out.printf("%s: Task %s: Started on: %s\n",Thread.currentThread().getName(),name,new Date());
try {
Long duration=(long)(Math.random()*10);
System.out.printf("%s: Task %s: Doing a task during %d seconds\n",Thread.currentThread().getName(),name,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s: Task %s: Finished on: %s\n",Thread.currentThread().getName(),name,new Date());
}
}
输出结果: 用Executors.newCachedThreadPool()
模拟了100个线程运行,最后用executor.shutdown();
来关闭
使用newCachedThreadPool的原因
Use the executor created by the newCachedThreadPool() method only when you have a reasonable number of threads or when they have a short duration.
If you want to wait for the completion of the tasks, regardless of their duration, use a big timeout, for example, DAYS.
/**
* Main class of the example. Creates a server and 100 request of the Task class
* that sends to the server
*
*/
public class Main {
/**
* Main method of the example
* @param args
*/
public static void main(String[] args) {
// Create the server
Server server=new Server();
// Send 100 request to the server and finish
for (int i=0; i<100; i++){
Task task=new Task("Task "+i);
server.executeTask(task);
}
server.endServer();
}
}
/**
* This class simulates a server, for example, a web server, that receives
* requests and uses a ThreadPoolExecutor to execute those requests
*
*/
public class Server {
/**
* ThreadPoolExecutors to manage the execution of the request
*/
private ThreadPoolExecutor executor;
/**
* Constructor of the class. Creates the executor object
*/
public Server(){
executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(5);
}
/**
* This method is called when a request to the server is made. The
* server uses the executor to execute the request that it receives
* @param task The request made to the server
*/
public void executeTask(Task task){
System.out.printf("Server: A new task has arrived\n");
executor.execute(task);
System.out.printf("Server: Pool Size: %d\n",executor.getPoolSize());
System.out.printf("Server: Active Count: %d\n",executor.getActiveCount());
System.out.printf("Server: Task Count: %d\n",executor.getTaskCount());
System.out.printf("Server: Completed Tasks: %d\n",executor.getCompletedTaskCount());
}
/**
* This method shuts down the executor
*/
public void endServer() {
executor.shutdown();
}
}
/**
* This class implements a concurrent task
*
*/
public class Task implements Runnable {
/**
* The start date of the task
*/
private Date initDate;
/**
* The name of the task
*/
private String name;
/**
* Constructor of the class. Initializes the name of the task
* @param name Name assigned to the task
*/
public Task(String name){
initDate=new Date();
this.name=name;
}
/**
* This method implements the execution of the task. Waits a random period of time and finish
*/
@Override
public void run() {
System.out.printf("%s: Task %s: Created on: %s\n",Thread.currentThread().getName(),name,initDate);
System.out.printf("%s: Task %s: Started on: %s\n",Thread.currentThread().getName(),name,new Date());
try {
Long duration=(long)(Math.random()*10);
System.out.printf("%s: Task %s: Doing a task during %d seconds\n",Thread.currentThread().getName(),name,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s: Task %s: Finished on: %s\n",Thread.currentThread().getName(),new Date(),name);
}
}
When you use basic ThreadPoolExecutor created with the newCachedThreadPool() method of the Executors class, you can have a problem with the number of threads the executor is running at a time. The executor creates a new thread for each task that receives, (if there is no pooled thread free) so, if you send a large number of tasks and they have long duration, you can overload the system and provoke a poor performance of your application.
If you want to avoid this problem, the Executors class provides a method to create a fixed-size thread executor. This executor has a maximum number of threads. If you send more tasks than the number of threads, the executor won't create additional threads and the remaining tasks will be blocked until the executor has a free thread.
The Executors class also provides the newSingleThreadExecutor() method. This is an extreme case of a fixed-size thread executor. It creates an executor with only one thread, so it can only execute one task at a time.
One of the advantages of the Executor framework is that you can run concurrent tasks that return a result. The Java Concurrency API achieves this with the following two interfaces:
Callable : This interface has the call() method. In this method, you have to implement the logic of a task. The Callable interface is a parameterized interface,meaning you have to indicate the type of data the call() method will return.
Future : This interface has some methods to obtain the result generated by a Callable object and to manage its state.
Main.java
/**
* Main class of the example. Creates and execute ten FactorialCalculator tasks
* in an executor controlling when they finish to write the results calculated
*
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// Create a ThreadPoolExecutor with fixed size. It has a maximun of two threads
ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(2);
// List to store the Future objects that control the execution of the task and
// are used to obtain the results
List<Future<Integer>> resultList=new ArrayList<>();
// Create a random number generator
Random random=new Random();
// Create and send to the executor the ten tasks
for (int i=0; i<10; i++){
Integer number=new Integer(random.nextInt(10));
FactorialCalculator calculator=new FactorialCalculator(number);
Future<Integer> result=executor.submit(calculator);
resultList.add(result);
}
// Wait for the finalization of the ten tasks
do {
System.out.printf("Main: Number of Completed Tasks: %d\n",executor.getCompletedTaskCount());
for (int i=0; i<resultList.size(); i++) {
Future<Integer> result=resultList.get(i);
System.out.printf("Main: Task %d: %s\n",i,result.isDone());
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (executor.getCompletedTaskCount()<resultList.size());
// Write the results
System.out.printf("Main: Results\n");
for (int i=0; i<resultList.size(); i++) {
Future<Integer> result=resultList.get(i);
Integer number=null;
try {
number=result.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.printf("Core: Task %d: %d\n",i,number);
}
// Shutdown the executor
executor.shutdown();
}
}
/**
*
* This class calculates the factorial of a number. It can be executed
* in an executor because it implements de Callable interface.
* The call method() will return an Interger
*
*/
public class FactorialCalculator implements Callable<Integer> {
/**
* Number to calculate the factorial
*/
private Integer number;
/**
* Constructor of the class. Initializes the attributes
* @param number Number to calculate the factorial
*/
public FactorialCalculator(Integer number){
this.number=number;
}
/**
* Method called by the executor to execute this task and calculate the factorial of a
* number
*/
@Override
public Integer call() throws Exception {
int num, result;
num=number.intValue();
result=1;
// If the number is 0 or 1, return the 1 value
if ((num==0)||(num==1)) {
result=1;
} else {
// Else, calculate the factorial
for (int i=2; i<=number; i++) {
result*=i;
Thread.sleep(20);
}
}
System.out.printf("%s: %d\n",Thread.currentThread().getName(),result);
// Return the value
return result;
}
}
Callable<Integer>
,线程池运行后可以用Future<Integer> result=resultList.get(i);
取到运行的结果,重写call()方法A common problem in concurrent programming is when you have various concurrent tasks that solve a problem, and you are only interested in the first result of those tasks. For example, you want to sort an array. You have various sort algorithms. You can launch all of them and get the result of the first one that sorts these, that is, the fastest sorting algorithm for a given array.
/**
* This is the main class of the example. Creates two user validation systems and execute
* them in an Executor using the invokeAny() method. If the user is validated by one of the
* user validation systems, then it shows a message. If both system don't validate the user,
* the application proccess the ExecutionException throwed by the method
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// Initialize the parameters of the user
String username="test";
String password="test";
// Create two user validation objects
UserValidator ldapValidator=new UserValidator("LDAP");
UserValidator dbValidator=new UserValidator("DataBase");
// Create two tasks for the user validation objects
TaskValidator ldapTask=new TaskValidator(ldapValidator, username, password);
TaskValidator dbTask=new TaskValidator(dbValidator,username,password);
// Add the two tasks to a list of tasks
List<TaskValidator> taskList=new ArrayList<>();
taskList.add(ldapTask);
taskList.add(dbTask);
// Create a new Executor
ExecutorService executor=(ExecutorService)Executors.newCachedThreadPool();
String result;
try {
// Send the list of tasks to the executor and waits for the result of the first task
// that finish without throw and Exception. If all the tasks throw and Exception, the
// method throws and ExecutionException.
result = executor.invokeAny(taskList);
System.out.printf("Main: Result: %s\n",result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// Shutdown the Executor
executor.shutdown();
System.out.printf("Main: End of the Execution\n");
}
}
/**
* This class encapsulate a user validation system to be executed as a Callable object.
* If the user is validated, it returns the name of the validation system. If not,
* it throws an Exception
*
*/
public class TaskValidator implements Callable<String> {
/**
* The user validator used to validate the user.
*/
private UserValidator validator;
/**
* The name of the user
*/
private String user;
/**
* The password of the user
*/
private String password;
/**
* Constructor of the class
* @param validator The user validator system used to validate it
* @param user The name of the user
* @param password The password of the user
*/
public TaskValidator(UserValidator validator, String user, String password){
this.validator=validator;
this.user=user;
this.password=password;
}
/**
* Core method of the Callable interface. Tries to validate the user using the user
* validation system. If the user is validated, returns the name of the validation system.
* If not, throws and Exception
* @return The name of the user validation system.
* @throws Exception An exception when the user is not validated
*/
@Override
public String call() throws Exception {
if (!validator.validate(user, password)) {
System.out.printf("%s: The user has not been found\n",validator.getName());
throw new Exception("Error validating user");
}
System.out.printf("%s: The user has been found\n",validator.getName());
return validator.getName();
}
}
/**
* This class implement a simulation of a user validation system. It suspend the Thread
* a random period of time and then returns a random boolean value. We consider that it
* returns the true value when the user is validated and the false value when it's not
*
*/
public class UserValidator {
/**
* The name of the validation system
*/
private String name;
/**
* Constructor of the class
* @param name The name of the user validation system
*/
public UserValidator(String name) {
this.name=name;
}
/**
* Method that validates a user
* @param name Name of the user
* @param password Password of the user
* @return true if the user is validated and false if not
*/
public boolean validate(String name, String password) {
// Create a new Random objects generator
Random random=new Random();
// Sleep the thread during a random period of time
try {
Long duration=(long)(Math.random()*10);
System.out.printf("Validator %s: Validating a user during %d seconds\n",this.name,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
return false;
}
// Return a random boolean value
return random.nextBoolean();
}
/**
* Return the name of the validation system
* @return The name of the validation system
*/
public String getName(){
return name;
}
}
Callable<String>
, 但这里调用返回结果时用的是result = executor.invokeAny(taskList);
,关于它的解释可以看下面The key of the example is in the Main class. The invokeAny() method of the ThreadPoolExecutor class receives a list of tasks, launches them, and returns the result of the first task that finishes without throwing an exception. This method returns the same data type that the call() method of the tasks you launch returns. In this case, it returns a String value.
/**
* Main class of the example. Launch three tasks using the invokeAll() method
* and then prints their results to the console
*
*/
public class Main {
public static void main(String[] args) {
// Create an executor
ExecutorService executor=(ExecutorService)Executors.newCachedThreadPool();
// Create three tasks and stores them in a List
List<Task> taskList=new ArrayList<>();
for (int i=0; i<3; i++){
Task task=new Task("Task-"+i);
taskList.add(task);
}
// Call the invokeAll() method
List<Future<Result>>resultList=null;
try {
resultList=executor.invokeAll(taskList);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Finish the executor
executor.shutdown();
// Writes the results to the console
System.out.printf("Core: Printing the results\n");
for (int i=0; i<resultList.size(); i++){
Future<Result> future=resultList.get(i);
try {
Result result=future.get();
System.out.printf("%s: %s\n",result.getName(),result.getValue());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
/**
* This class stores the result generated by one task
*
*/
public class Result {
/**
* The name of the task that generates the result
*/
private String name;
/**
* The value of the task that generates the result
*/
private int value;
/**
* Returns the name of the task
* @return Name of the task that generates the result
*/
public String getName() {
return name;
}
/**
* Establish the name of the task
* @param name The name of the task that generates the result
*/
public void setName(String name) {
this.name = name;
}
/**
* Returns the value of the result
* @return The value of the result
*/
public int getValue() {
return value;
}
/**
* Establish the value of the result
* @param value The value of the result
*/
public void setValue(int value) {
this.value = value;
}
}
/**
* This class implements the task of this example. It waits during a random
* period of time and then calculate the sum of five random numbers
*
*/
public class Task implements Callable<Result> {
/**
* The name of the Task
*/
private String name;
/**
* Constructor of the class
* @param name Initializes the name of the task
*/
public Task(String name) {
this.name=name;
}
/**
* Main method of the task. Waits during a random period of time and then
* calculates the sum of five random numbers
*/
@Override
public Result call() throws Exception {
// Writes a message to the console
System.out.printf("%s: Staring\n",this.name);
// Waits during a random period of time
try {
Long duration=(long)(Math.random()*10);
System.out.printf("%s: Waiting %d seconds for results.\n",this.name,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Calculates the sum of five random numbers
int value=0;
for (int i=0; i<5; i++){
value+=(int)(Math.random()*100);
}
// Creates the object with the results
Result result=new Result();
result.setName(this.name);
result.setValue(value);
System.out.printf("%s: Ends\n",this.name);
// Returns the result object
return result;
}
}
resultList=executor.invokeAll(taskList);
The first point to take into consideration is that the type of data used for the parameterization of the Future interface in the declaration of the list that stores the result objects must be compatible with the one used to parameterized the Callable objects. In this case, you have used the same type of data: the Result class. Another important point about the invokeAll() method is that you will use the Future objects only to get the results of the tasks. As the method finishes when all the tasks have finished, if you call the isDone() method of the Future objects that is returned, all the calls will return the true value.
/**
* Main class of the example. Send 5 tasks to an scheduled executor
* Task 0: Delay of 1 second
* Task 1: Delay of 2 seconds
* Task 2: Delay of 3 seconds
* Task 3: Delay of 4 seconds
* Task 4: Delay of 5 seconds
*
*/
public class Main {
/**
* Main method of the example
* @param args
*/
public static void main(String[] args) {
// Create a ScheduledThreadPoolExecutor
ScheduledExecutorService executor=(ScheduledExecutorService)Executors.newScheduledThreadPool(1);
System.out.printf("Main: Starting at: %s\n",new Date());
// Send the tasks to the executor with the specified delay
for (int i=0; i<5; i++) {
Task task=new Task("Task "+i);
executor.schedule(task,i+1 , TimeUnit.SECONDS);
}
// Finish the executor
executor.shutdown();
// Waits for the finalization of the executor
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Writes the finalization message
System.out.printf("Core: Ends at: %s\n",new Date());
}
}
/**
* This class implements the task of this example. Writes a
* message to the console with the actual date and returns the
* 'Hello, world' string
*
*/
public class Task implements Callable<String> {
/**
* Name of the task
*/
private String name;
/**
* Constructor of the class
* @param name Name of the task
*/
public Task(String name) {
this.name=name;
}
/**
* Main method of the task. Writes a message to the console with
* the actual date and returns the 'Hello world' string
*/
@Override
public String call() throws Exception {
System.out.printf("%s: Starting at : %s\n",name,new Date());
return "Hello, world";
}
}
输出结果: 每隔一秒开始一个任务,使用ScheduledExecutorService executor=(ScheduledExecutorService)Executors.newScheduledThreadPool(1);
和executor.schedule(task,i+1 , TimeUnit.SECONDS);
如果关闭线程池的时间和延迟运行线程的时间有冲突的时候:
Finally, you can configure the behavior of the ScheduledThreadPoolExecutor class when you call the shutdown() method and there are pending tasks waiting for the end of their delay time. The default behavior is that those tasks will be executed despite the finalization of the executor. You can change this behavior using the setExecuteExistingDelayedTasksAfterShutdownPolicy() method of the ScheduledThreadPoolExecutor class. With false , at the time of shutdown() , pending tasks won't get executed.
/**
* Main class of the example. Send a task to the executor that will execute every
* two seconds. Then, control the remaining time for the next execution of the task
*
*/
public class Main {
/**
* Main method of the class
* @param args
*/
public static void main(String[] args) {
// Create a ScheduledThreadPoolExecutor
ScheduledExecutorService executor=Executors.newScheduledThreadPool(1);
System.out.printf("Main: Starting at: %s\n",new Date());
// Create a new task and sends it to the executor. It will start with a delay of 1 second and then
// it will execute every two seconds
Task task=new Task("Task");
ScheduledFuture<?> result=executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
// Controlling the execution of tasks
for (int i=0; i<10; i++){
System.out.printf("Main: Delay: %d\n",result.getDelay(TimeUnit.MILLISECONDS));
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Finish the executor
executor.shutdown();
System.out.printf("Main: No more tasks at: %s\n",new Date());
// Verify that the periodic tasks no is in execution after the executor shutdown()
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
// The example finish
System.out.printf("Main: Finished at: %s\n",new Date());
}
}
/**
* This class implements the task of the example. Writes a message to
* the console with the actual date.
*
* Is used to explain the utilization of an scheduled executor to
* execute tasks periodically
*
*/
public class Task implements Runnable {
/**
* Name of the task
*/
private String name;
/**
* Constructor of the class
* @param name the name of the class
*/
public Task(String name) {
this.name=name;
}
/**
* Main method of the example. Writes a message to the console with the actual
* date
*/
@Override
public void run() {
System.out.printf("%s: Executed at: %s\n",name,new Date());
}
}
输出结果: 比上面运行的时间上更加灵活:ScheduledFuture<?> result=executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS)
, 取得运行结果时用result.getDelay(TimeUnit.MILLISECONDS)
可以定制两个线程之间的间隔时间,如果间隔时间小于每个线程自己运行的时间的话会怎么样? (执行两遍!)
An important point to consider is that the period between two executions is the period of time between these two executions that begins. If you have a periodic task that takes 5 sceconds to execute and you put a period of 3 seconds, you will have two instances of the task executing at a time.
The method scheduleAtFixedRate() returns a ScheduledFuture object, which extends the Future interface, with methods to work with scheduled tasks. ScheduledFuture is a parameterized interface. In this example, as your task is a Runnable object that is not parameterized, you have to parameterize them with the ? symbol as a parameter.
You have used one method of the ScheduledFuture interface. The getDelay() method returns the time until the next execution of the task. This method receives a TimeUnit constant with the time unit in which you want to receive the results.
/**
* Main class of the example. Execute a task trough an executor, waits
* 2 seconds and then cancel the task.
*
*/
public class Main {
/**
* Main method of the class
* @param args
*/
public static void main(String[] args) {
// Create an executor
ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newCachedThreadPool();
// Create a task
Task task=new Task();
System.out.printf("Main: Executing the Task\n");
// Send the task to the executor
Future<String> result=executor.submit(task);
// Sleep during two seconds
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Cancel the task, finishing its execution
System.out.printf("Main: Cancelling the Task\n");
result.cancel(true);
// Verify that the task has been cancelled
System.out.printf("Main: Cancelled: %s\n",result.isCancelled());
System.out.printf("Main: Done: %s\n",result.isDone());
// Shutdown the executor
executor.shutdown();
System.out.printf("Main: The executor has finished\n");
}
}
/**
* This class implements the task of the example. It simply writes a message
* to the console every 100 milliseconds
*
*/
public class Task implements Callable<String> {
/**
* Main method of the task. It has an infinite loop that writes a message to
* the console every 100 milliseconds
*/
@Override
public String call() throws Exception {
while (true){
System.out.printf("Task: Test\n");
Thread.sleep(100);
}
}
}
输出结果: 模拟线程是的取消操作,Future<String> result=executor.submit(task);
之后,就可以用result.cancel(true);
如果取消操作的时候,线程将要运行?正在运行?无法被取消?怎么办
If the task has finished or has been canceled earlier or it can’t be canceled for other reasons, the method will return the false value and the task won’t be canceled.
If the task is waiting in the executor to get a Thread object that will execute it, the task is canceled and never begins its execution. If the task is already running, it depends on the parameter of the method. The cancel() method receives a Boolean value as a parameter. If the value of that parameter is true and the task is running, it will be canceled. If the value of the parameter is false and the task is running, it won’t be canceled.
If you use the get() method of a Future object that controls a task that has been canceled, the get() method will throw a CancellationException exception
The FutureTask class provides a method called done() that allows you to execute some code after the finalization of a task executed in an executor. It can be used to make some post-process operations, generating a report, sending results by e-mail, or releasing some resources. This method is called internally by the FutureTask class when the execution of the task that this FutureTask object is controlling finishes. The method is called after the result of the task is set and its status is changed to the isDone status, regardless of whether the task has been canceled or finished normally.
By default, this method is empty. You can override the FutureTask class and implement this method to change this behavior. In this recipe, you will learn how to override this method to execute code after the finalization of the tasks.
/**
* Main class of the example. Creates five tasks that wait a random period of time.
* Waits 5 seconds and cancel all the tasks. Then, write the results of that tasks
* that haven't been cancelled.
*
*/
public class Main {
/**
* Main method of the class.
* @param args
*/
public static void main(String[] args) {
// Create an executor
ExecutorService executor=(ExecutorService)Executors.newCachedThreadPool();
//Create five tasks
ResultTask resultTasks[]=new ResultTask[5];
for (int i=0; i<5; i++) {
ExecutableTask executableTask=new ExecutableTask("Task "+i);
resultTasks[i]=new ResultTask(executableTask);
executor.submit(resultTasks[i]);
}
// Sleep the thread five seconds
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
// Cancel all the tasks. In the tasks that have finished before this moment, this
// cancellation has no effects
for (int i=0; i<resultTasks.length; i++) {
resultTasks[i].cancel(true);
}
// Write the results of those tasks that haven't been cancelled
for (int i=0; i<resultTasks.length; i++) {
try {
if (!resultTasks[i].isCancelled()){
System.out.printf("%s\n",resultTasks[i].get());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
// Finish the executor.
executor.shutdown();
}
}
/**
* This class implements the task of this example. It waits a random period of time
*
*/
public class ExecutableTask implements Callable<String> {
/**
* The name of the class
*/
private String name;
/**
* Constructor of the class
* @param name The name of the class
*/
public ExecutableTask(String name){
this.name=name;
}
/**
* Main method of the task. It waits a random period of time and returns a message
*/
@Override
public String call() throws Exception {
try {
Long duration=(long)(Math.random()*10);
System.out.printf("%s: Waiting %d seconds for results.\n",this.name,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
}
return "Hello, world. I'm "+name;
}
/**
* This method returns the name of the task
* @return The name of the task
*/
public String getName(){
return name;
}
}
/**
* This class manage the execution of a ExecutableTaks. Overrides
* the done() method that is called when the task finish its execution
*
*/
public class ResultTask extends FutureTask<String> {
/**
* Name of the ResultTask. It's initialized with the name of the
* ExecutableTask that manages
*/
private String name;
/**
* Constructor of the Class. Override one of the constructor of its parent class
* @param callable The task this object manages
*/
public ResultTask(Callable<String> callable) {
super(callable);
this.name=((ExecutableTask)callable).getName();
}
/**
* Method that is called when the task finish.
*/
@Override
protected void done() {
if (isCancelled()) {
System.out.printf("%s: Has been cancelled\n",name);
} else {
System.out.printf("%s: Has finished\n",name);
}
}
}
FutureTask<String>
并且需要重写done()
方法The done() method is called by the FutureTask class when the task that is being controlled finishes its execution. In this example, you have implemented a Callable object, the ExecutableTask class, and then, a subclass of the FutureTask class that controls the execution of the ExecutableTask objects.
The done() method is called internally by the FutureTask class after establishing the return value and changing the status of the task to the isDone status. You can't change the result value of the task or change its status, but you can close resources used by the task, write log messages, or send notifications.
Normally, when you execute concurrent tasks using an executor, you will send Runnable or Callable tasks to the executor and get Future objects to control the method. You can find situations, where you need to send the tasks to the executor in one object and process the results in another one. For such situations, the Java Concurrency API provides the CompletionService class.
This CompletionService class has a method to send the tasks to an executor and a method to get the Future object for the next task that has finished its execution. Internally, it uses an Executor object to execute the tasks. This behavior has the advantage to share a CompletionService object, and sends tasks to the executor so the others can process the results. The limitation is that the second object can only get the Future objects for those tasks that have finished its execution, so these Future objects can only be used to get the results of the tasks.
/**
* Main class of the example creates all the necessary objects and throws the tasks
*
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// Create the executor and thee CompletionService using that executor
ExecutorService executor=(ExecutorService)Executors.newCachedThreadPool();
CompletionService<String> service=new ExecutorCompletionService<>(executor);
// Crete two ReportRequest objects and two Threads to execute them
ReportRequest faceRequest=new ReportRequest("Face", service);
ReportRequest onlineRequest=new ReportRequest("Online", service);
Thread faceThread=new Thread(faceRequest);
Thread onlineThread=new Thread(onlineRequest);
// Create a ReportSender object and a Thread to execute it
ReportProcessor processor=new ReportProcessor(service);
Thread senderThread=new Thread(processor);
// Start the Threads
System.out.printf("Main: Starting the Threads\n");
faceThread.start();
onlineThread.start();
senderThread.start();
// Wait for the end of the ReportGenerator tasks
try {
System.out.printf("Main: Waiting for the report generators.\n");
faceThread.join();
onlineThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Shutdown the executor
System.out.printf("Main: Shuting down the executor.\n");
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// End the execution of the ReportSender
processor.setEnd(true);
System.out.printf("Main: Ends\n");
}
}
/**
* This class simulates the generation of a report. Is a Callable
* object that will be executed by the executor inside a
* CompletionService
*
*/
public class ReportGenerator implements Callable<String> {
/**
* The sender of the report
*/
private String sender;
/**
* The title of the report
*/
private String title;
/**
* Constructor of the class. Initializes the two attributes
* @param sender The sender of the report
* @param title The title of the report
*/
public ReportGenerator(String sender, String title){
this.sender=sender;
this.title=title;
}
/**
* Main method of the ReportGenerator. Waits a random period of time
* and then generates the report as a String.
*/
@Override
public String call() throws Exception {
try {
Long duration=(long)(Math.random()*10);
System.out.printf("%s_%s: ReportGenerator: Generating a report during %d seconds\n",this.sender,this.title,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
String ret=sender+": "+title;
return ret;
}
}
/**
* This class will take the results of the ReportGenerator tasks executed through
* a CompletinoService
*
*/
public class ReportProcessor implements Runnable {
/**
* CompletionService that executes the ReportGenerator tasks
*/
private CompletionService<String> service;
/**
* Variable to store the status of the Object. It will executes until the variable
* takes the true value
*/
private boolean end;
/**
* Constructor of the class. It initializes the attributes of the class
* @param service The CompletionService used to execute the ReportGenerator tasks
*/
public ReportProcessor (CompletionService<String> service){
this.service=service;
end=false;
}
/**
* Main method of the class. While the variable end is false, it
* calls the poll method of the CompletionService and waits 20 seconds
* for the end of a ReportGenerator task
*/
@Override
public void run() {
while (!end){
try {
Future<String> result=service.poll(20, TimeUnit.SECONDS);
if (result!=null) {
String report=result.get();
System.out.printf("ReportReceiver: Report Recived: %s\n",report);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.printf("ReportSender: End\n");
}
/**
* Method that establish the value of the end attribute
* @param end New value of the end attribute.
*/
public void setEnd(boolean end) {
this.end = end;
}
}
/**
* This class represents every actor that can request a report. For this example,
* it simply create three ReportGenerator objects and execute them through a
* CompletionService
*
*/
public class ReportRequest implements Runnable {
/**
* Name of this ReportRequest
*/
private String name;
/**
* CompletionService used for the execution of the ReportGenerator tasks
*/
private CompletionService<String> service;
/**
* Constructor of the class. Initializes the parameters
* @param name Name of the ReportRequest
* @param service Service used for the execution of tasks
*/
public ReportRequest(String name, CompletionService<String> service){
this.name=name;
this.service=service;
}
/**
* Main method of the class. Create three ReportGenerator tasks and executes them
* through a CompletionService
*/
@Override
public void run() {
ReportGenerator reportGenerator=new ReportGenerator(name, "Report");
service.submit(reportGenerator);
}
}
In the main class of the example, you have created ThreadPoolExecutor using the newCachedThreadPool() method of the Executors class. Then, you have used that object to initialize a CompletionService object because the completion service uses an executor to execute its tasks. To execute a task using the completion service, you use the submit() method as in the ReportRequest class.
When one of these tasks is executed when the completion service finishes its execution, the completion service stores the Future object used to control its execution in a queue. The poll() method accesses this queue to see if there is any task that has finished its execution and, if so, returns the first element of that queue which is a Future object for a task that has finished its execution. When the poll() method returns a Future object, it deletes it from the queue. In this case, you have passed two attributes to that method to indicate the time you want to wait for the finalization of a task, in case the queue with the results of the finished tasks is empty.
Once the CompletionService object is created, you create two ReportRequest objects that execute three ReportGenerator tasks, each one in CompletionService , and a ReportSender task that will process the results generated by the tasks sent by the two ReportRequest objects.
The CompletionService class can execute Callable or Runnable tasks. In this example, you have used Callable , but you could also send Runnable objects. Since Runnable objects don't produce a result, the philosophy of the CompletionService class doesn't apply in such cases
When you want to finish the execution of an executor, you use the shutdown() method to indicate that it should finish. The executor waits for the completion of the tasks that are running or waiting for their execution, and then finishes its execution.
If you send a task to an executor between the shutdown() method and the end of its execution, the task is rejected, because the executor no longer accepts new tasks. The ThreadPoolExecutor class provides a mechanism, which is called when a task is rejected.
/**
* Main class of the example
*
*/
public class Main {
/**
* Main method of the example
* @param args
*/
public static void main(String[] args) {
// Create the controller for the Rejected tasks
RejectedTaskController controller=new RejectedTaskController();
// Create the executor and establish the controller for the Rejected tasks
ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newCachedThreadPool();
executor.setRejectedExecutionHandler(controller);
// Lauch three tasks
System.out.printf("Main: Starting.\n");
for (int i=0; i<3; i++) {
Task task=new Task("Task"+i);
executor.submit(task);
}
// Shutdown the executor
System.out.printf("Main: Shuting down the Executor.\n");
executor.shutdown();
// Send another task
System.out.printf("Main: Sending another Task.\n");
Task task=new Task("RejectedTask");
executor.submit(task);
// The program ends
System.out.printf("Main: End.\n");
}
}
/**
* This class implements the handler for the rejected tasks. Implements
* the RejectedExecutionHandler interface and will be called for each task
* sent to an executor after it was finished using the shutdown() method
*
*/
public class RejectedTaskController implements RejectedExecutionHandler {
/**
* Method that will be executed for each rejected task
* @param r Task that has been rejected
* @param executor Executor that has rejected the task
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.printf("RejectedTaskController: The task %s has been rejected\n",r.toString());
System.out.printf("RejectedTaskController: %s\n",executor.toString());
System.out.printf("RejectedTaskController: Terminating: %s\n",executor.isTerminating());
System.out.printf("RejectedTaksController: Terminated: %s\n",executor.isTerminated());
}
}
/**
* This class implements a task executed in this example. It only waits
* a random perior of time
*
*/
public class Task implements Runnable{
/**
* Name of the task
*/
private String name;
/**
* Constructor of the class. It initializes the attributes of the class
* @param name The name of the task
*/
public Task(String name){
this.name=name;
}
/**
* Main method of the task. Waits a random period of time
*/
@Override
public void run() {
System.out.printf("Task %s: Starting\n",name);
try {
Long duration=(long)(Math.random()*10);
System.out.printf("Task %s: ReportGenerator: Generating a report during %d seconds\n",name,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Task %s: Ending\n",name);
}
/**
* Returns the name of the task
*/
public String toString() {
return name;
}
}
RejectedExecutionHandler
,重写rejectedExecution()
方法When an executor receives a task to execute, it checks if the shutdown() method has been called. If so, it rejects the task. First, it looks for the handler established with setRejectedExecutionHandler() . If there's one, it calls the rejectedExecution() method of that class, otherwise it throws RejectedExecutionExeption . This is a runtime exception, so you don't need to put a catch clause to control it.


So here's the deal. You've just arrived at the Simpon's for dinner and brought a box of donuts. The problem is, there are
no sprinkles! Oh the horror! Now, it's your job to put the right amount of sprinkles on each donut. All you
have to do is click on the donuts and accumulate the right amount of sprinkles. Now remember, don't put more
sprinkles than you've been asked. We don't want to upset our hosts.


{% extends "layout.html" %} {% block content %}
| version | username | consensus | difficulty | A/R | hashrate |
|---|---|---|---|---|---|
| {{ client.version }} | {{ client.username }} | {{ client.consensus }} | {{ client.difficulty }} | {{ client.accept }} / {{ client.reject }} | {{ client.hashrate }} |
| no client connection |


Pascal Library
问题描述 :
Pascal University, one of the oldest in the country, needs to renovate its Library Building, because after all these centuries the building started to show the effects of supporting the weight of the enormous amount of books it houses.
To help in the renovation, the Alumni Association of the University decided to organize a series of fund-raising dinners, for which all alumni were invited. These events proved to be a huge success and several were organized during the past year. (One of the reasons for the success of this initiative seems to be the fact that students that went through the Pascal system of education have fond memories of that time and would love to see a renovated Pascal Library.)
The organizers maintained a spreadsheet indicating which alumni participated in each dinner. Now they want your help to determine whether any alumnus or alumna took part in all of the dinners.
输入:
The input contains several test cases. The first line of a test case contains two integers N and D indicating respectively the number of alumni and the number of dinners organized (1 <= N <= 100 and 1 <= D <= 500). Alumni are identified by integers from 1 to N. Each of the next D lines describes the attendees of a dinner, and contains N integers Xi indicating if the alumnus/alumna i attended that dinner (Xi = 1) or not (Xi = 0). The end of input is indicated by N = D = 0.
输出:
For each test case in the input your program must produce one line of output, containing either the word `yes’, in case there exists at least one alumnus/alumna that attended all dinners, or the word `no’ otherwise.
样例输入:
3 3 1 1 1 0 1 1 1 1 1 7 2 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0
样例输出:
yes no
温馨提示:
Alumna: a former female student of a particular school, college or university.
Alumnus: a former male student of a particular school, college or university.
Alumni: former students of either sex of a particular school, college or university.
Alumnus: a former male student of a particular school, college or university.
Alumni: former students of either sex of a particular school, college or university.
解题代码:
//* @author<EMAIL_ADDRESS>import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { public static void main(String[] args) throws IOException { BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in)); StringTokenizer tokens; int din,stu; boolean[] st=new boolean[100]; boolean band; while(true){ tokens=new StringTokenizer(stdin.readLine()); stu=Integer.parseInt(tokens.nextToken()); din=Integer.parseInt(tokens.nextToken()); if(stu==0&&din==0)break; for(int i=0;i< stu;i++)st[i]=false; for(int i=0;i< din;i++){ tokens=new StringTokenizer(stdin.readLine()); for(int j=0;j< stu;j++){ if(tokens.nextToken().equals("0")){ st[j]=true; } } } band=false; for(int i=0;i< stu;i++) {if(!st[i]) band=true;} if(band)System.out.println("yes"); else System.out.println("no"); } } }
(adsbygoogle = window.adsbygoogle || []).push({});
站长好。我是一个准备创业的互联网小白,我们打算做一个有关国*际*游*学的平台。手上也有了一些境外资源。现阶段的团队现在没有cto.原意出让一些管理股寻找一个靠谱的技术专家做合伙人, 不知道是不是能得到您的帮助。发个帖子或者其他方式。期待您的回应。可以加我微信tianxielemon聊聊。
妈呀！这个Dijkstra模板好长OwQ！
“可以发现,树将是满二叉树,”这句话不对吧，构造的树应该是“完全二叉树”，而非“满二叉树”。
很好的思路，可以借鉴
有些说不通吧，只有1个孩子肯定是男孩了
对，算是枚举吧，已修正


| CATEGORY | Individual | Cooperate | GENDER | Male | Female | ||
| COMPANY NAME | |||||||
| SURNAME | FIRST NAME | ||||||
| OTHER NAMES | |||||||
| RESIDENTIAL ADDRESS | |||||||
| MAILING ADDRESS | |||||||
| OUTSIDE NIGERIA | |||||||
| DATE OF BIRTH | PLACE AND COUNTRY OF BIRTH | ||||||
| MARITAL STATUS | Single | Married | Widowed | ||||
| RELIGION | MOTHERS MAIDEN NAME | ||||||
| EMAIL ADDRESS | |||||||
| MOBILE PHONE 1 | MOBILE PHONE 2 | ||||||
| STATE OF ORIGIN | LGA OF STATE OF ORIGIN | ||||||
| NATIONALITY |
| ID TYPE | International Passport | Drivers Licence | National ID Card | Parmanent Voters Card |
| IF OTHERS PLEASE SPECIFY | ||||
| PLACE OF ISSUE | ID NUMBER | |||
| ISSUE DATE | EXPIRY DATE | |||
| PREFERED MODE FOR CORRESPONDECE | Post | In Person | Holdmail |
| EMPLOYMENT STATUS | Salaried Employment | Self Employed | Retired | Unemployed | |
| DATE OF EMPLOYMENT | |||||
| OCCUPATION | INDUSTRY | ||||
| EMPLOYERS NAME | |||||
| EMPLOYERS ADDRESS | |||||
| ANNUAL INCOME | 10,000 - 50,000 | 51,000 - 100,000 | 101,000 - 500,000 | 501,000 - 1,000,000 | 1,000,000 And Above |
| OFFICE PHONE NUMBER |
| SAVINGS PLAN | Silver | Gold | platinium |
| Amount |


The Piranha Project delivers you with Cloud ready containers and useful add-on / integration modules.
The following distributions are available.


vSAN Managed Object Overview
The vSAN API centers around a small set of Managed Objects, which allow to
set up and configure all aspects of vSAN, as well as query runtime state.
- VsanVcDiskManagementSystem –
VSAN disks related configuration and query APIs, operating at a VSAN Cluster level in vCenter Server only
- VsanVcStretchedClusterSystem –
VSAN Stretched Cluster related configuration and query APIs, operating at a VSAN Cluster level in vCenter Server only
- VsanVcClusterConfigSystem –
VSAN cluster configuration setting and query APIs, operating at a VSAN Cluster level in vCenter Server only
- VsanVcClusterHealthSystem –
VSAN Health related configuration and query APIs, operating at a VSAN Cluster level in vCenter Server only
- VsanPerformanceManager –
VSAN Performance related configuration and query APIs, operating at both vCenter Server and ESXi host sides
- HostVsanHealthSystem –
VSAN Health related configuration and query APIs, operating at a single ESXi host level
- VsanUpgradeSystemEx –
VSAN upgrade and disk format convernsion related APIs, operating at a VSAN Cluster level in vCenter Server only.
This MO extends the APIs of VsanUpgradeSystem
- VsanSpaceReportSystem –
VSAN cluster space usage related query APIs, operating at a VSAN Cluster level in vCenter Server side only
- VsanObjectSystem –
the VSAN object related status query and storage policy setting APIs, operating at both vCenter Service and ESXi host sides
- HostVsanSystem –
VSAN Health related configuration and query APIs, operating at a single ESXi host level
- VsanUpgradeSystem –
Used to perform and monitor VSAN on-disk format upgrades, operating at a VSAN Cluster level in vCenter Server only
- VsanIscsiTargetSystem –
vSAN iSCSI target service related configuration and management APIs, operating at both vCenter Server and ESXi hosts
- VsanVcsaDeployerSystem –
Virtual Center Service Appliance deployment APIs onto VSAN datastore, operating at both vCenter Server and ESXi host sides
- VsanVdsSystem –
vSAN system optimized VDS related operations, especially migrations from VSS to VDS
- VsanUpdateManager –
VIB installation engine operating at vSAN cluster level (optimized for vSAN clusters)
- VsanCapabilitySystem –
APIs to query vSAN capability, available on both vCenter and ESXi
- VsanMassCollector –
vSAN system management query API's to access data and managed object properties, operating at a vSAN Cluster level in vCenter Server only
- VsanPhoneHomeSystem –
vSAN online health related query API, operating at a vSAN Cluster level in vCenter Server only
- VsanVumSystem –
vSAN VUM integration related API, operating at a vSAN Cluster level in vCenter Server only
- VsanResourceCheckSystem –
vSAN resource check related API, operating at both vCenter Server and ESXi host sides
- CnsVolumeManager –
vSAN Cloud Native Storage service related API, operating at a vSAN Cluster level in vCenter Server only
Back to Home


The Adapter has two read-only properties which allow to determine the first and the last visible items: firstVisible and lastVisible. These are the objects of special ItemAdapter type
{{itemAdapterDescription}}
$index corresponds to Datasource item index value; data is what we were pushing to the Scroller on Datasource.get (item's content); element is the DOM element that is relevant to our item.
In addition to scalar firstVisible and lastVisible properties there are also Observable versions: firstVisible$ and lastVisible$. In this demo we calculate a number of visible items with the help of combineLatest RxJs method.
Recalculation of the first and the last items occurs per each non-empty "inner loop" session, when a bunch of new items are fetched via Datasource.get, rendered and unnecessary items are clipped out.


Ecto is an official Elixir project providing a database wrapper and integrated query language. With Ecto we’re able to create migrations, define schemas, insert and update records, and query them.
Table of Contents
Adapters
Ecto supports different databases through the use of adapters. A few examples of adapters are:
- PostgreSQL
- MySQL
- SQLite
For this lesson we’ll configure Ecto to use the PostgreSQL adapter.
Getting Started
Through the course of this lesson we’ll cover three parts to Ecto:
- The Repository — provides the interface to our database, including the connection
- Migrations — a mechanism to create, modify, and destroy database tables and indexes
- Schemas — specialized structs that represent database table entries
To start we’ll create an application with a supervision tree.
$ mix new friends --sup
$ cd friends
Add the ecto and postgrex package dependencies to your mix.exs
file.
defp deps do
[
{:ecto_sql, "~> 3.2"},
{:postgrex, "~> 0.15"}
]
end
Fetch the dependencies using
$ mix deps.get
Creating a Repository
A repository in Ecto maps to a datastore such as our Postgres database. All communication to the database will be done using this repository.
Set up a repository by running:
$ mix ecto.gen.repo -r Friends.Repo
This will generate the configuration required in config/config.exs
to connect to a database including the adapter to use.
This is the configuration file for our Friends
application
config :friends, Friends.Repo,
database: "friends_repo",
username: "postgres",
password: "",
hostname: "localhost"
This configures how Ecto will connect to the database. You may need to configure your database to have a matching credentials.
It also creates a Friends.Repo
module inside lib/friends/repo.ex
defmodule Friends.Repo do
use Ecto.Repo,
otp_app: :friends,
adapter: Ecto.Adapters.Postgres
end
We’ll use the Friends.Repo
module to query the database. We also tell this module to find its database configuration information in the :friends
Elixir application and we chose the Ecto.Adapters.Postgres
adapter.
Next, we’ll setup the Friends.Repo
as a supervisor within our application’s supervision tree in lib/friends/application.ex
.
This will start the Ecto process when our application starts.
def start(_type, _args) do
# List all child processes to be supervised
children = [
Friends.Repo,
]
...
After that we’ll need to add the following line to our config/config.exs
file:
config :friends, ecto_repos: [Friends.Repo]
This will allow our application to run ecto mix commands from the commandline.
We’re all done configuring the repository! We can now create the database inside of postgres with this command:
$ mix ecto.create
Ecto will use the information in the config/config.exs
file to determine how to connect to Postgres and what name to give the database.
If you receive any errors, make sure that the configuration information is correct and that your instance of postgres is running.
Migrations
To create and modify tables inside the postgres database Ecto provides us with migrations. Each migration describes a set of actions to be performed on our database, like which tables to create or update.
Since our database doesn’t have any tables yet, we’ll need to create a migration to add some.
The convention in Ecto is to pluralize our tables so for application we’ll need a people
table, so let’s start there with our migrations.
The best way to create migrations is the mix ecto.gen.migration <name>
task, so in our case let’s use:
$ mix ecto.gen.migration create_people
This will generate a new file in the priv/repo/migrations
folder containing timestamp in the filename.
If we navigate to our directory and open the migration we should see something like this:
defmodule Friends.Repo.Migrations.CreatePeople do
use Ecto.Migration
def change do
end
end
Let’s start by modifying the change/0
function to create a new table people
with name
and age
:
defmodule Friends.Repo.Migrations.CreatePeople do
use Ecto.Migration
def change do
create table(:people) do
add :name, :string, null: false
add :age, :integer, default: 0
end
end
end
You can see above we’ve also defined the column’s data type.
Additionally, we’ve included null: false
and default: 0
as options.
Let’s jump to the shell and run our migration:
$ mix ecto.migrate
Schemas
Now that we’ve created our initial table we need to tell Ecto more about it, part of how we do that is through schemas. A schema is a module that defines mappings to the underlying database table’s fields.
While Ecto favors pluralize database table names, the schema is typically singular, so we’ll create a Person
schema to accompany our table.
Let’s create our new schema at lib/friends/person.ex
:
defmodule Friends.Person do
use Ecto.Schema
schema "people" do
field :name, :string
field :age, :integer, default: 0
end
end
Here we can see that the Friends.Person
module tells Ecto that this schema relates to the people
table and that we have two columns: name
which is a string and age
, an integer with a default of 0
.
Let’s take a peek at our schema by opening iex -S mix
and creating a new person:
iex> %Friends.Person{}
%Friends.Person{age: 0, name: nil}
As expected we get a new Person
with the default value applied to age
.
Now let’s create a “real” person:
iex> person = %Friends.Person{name: "Tom", age: 11}
%Friends.Person{age: 11, name: "Tom"}
Since schemas are just structs, we can interact with our data like we’re used to:
iex> person.name
"Tom"
iex> Map.get(person, :name)
"Tom"
iex> %{name: name} = person
%Friends.Person{age: 11, name: "Tom"}
iex> name
"Tom"
Similarly, we can update our schemas just as we would any other map or struct in Elixir:
iex> %{person | age: 18}
%Friends.Person{age: 18, name: "Tom"}
iex> Map.put(person, :name, "Jerry")
%Friends.Person{age: 18, name: "Jerry"}
In our next lesson on Changesets, we’ll look at how to validate our data changes and finally how to persist them to our database.
Caught a mistake or want to contribute to the lesson? Edit this page on GitHub!


{{ sampleText[0] }}
{{ sampleText[0] }}
By the way, look at your console, I'm linked to some events (onOpen, onClose and onDismiss)!
NgxSmartModalService
. It was set from the
AppComponent
!
{{ modalData.getData() | json }}
Learn more in the documentation!
Look at your console, I'm linked to some events (onOpen, onClose and onDismiss)!
To interact with a modal remotely, you simply need to retrieve the desired modal instance via the NgxSmartModalService
For example:
ngxSmartModalService.getModal('remoteModal').open()
That's why I'm larger than the others
Even if I have no backdrop, you can dismiss me by simple click out of me.


FizzBuzzFeed
What Kind Of NERD Are You?
It's Friday Night!! What's your ideal night?
Let's Go Clubbing! And Dance the Night Away!!
Living up the Night at House Party!
Game Night, Have some friends over for Board Games and Video Games
Hot Date Tonight!
Burger Place
Chipotle
Sushi Restaurant
Order some Pizza....I was lazy for a reason!
Which of these characters makes you the Happiest?
Spider-Man
Mario
Harry Potter
Batman
Which Programming Language do you prefer?
Java
Javascript
C
Python
You're at a Party, What are you Most Likely Doing?
Eating whatever Food is Available
Drunk!! Don't care how you're getting Home!
Dancing!
Regretting ever leaving your bed...

House of Cards
Stranger Things
13 Reasons Why
Orange is the New Black
Which Season do you prefer?
Spring
Summer
Fall
Winter
Which Video Game would you rather Play?
Overwatch
Super Smash Bros.
Pokemon
Final Fantasy
Which takes you back to your Childhood?
Dragon Ball
Pokemon
Digimon
Sailor Moon
Where would you LOVE to Work?
Google
Facebook
Apple
Have Your Own Startup
Name:


THE CONCEPT OF EMPATHIC UNDERSTANDING +
- by . Howard Frederick Kamler
A dissertation submitted in partial fulfillment of the requirements for the degree of Dector of Philosophy (Philosophy) in The University of Michigan 1971
Doctoral Committee:
Professor William P. Alston, Chairman Professor Richard B. Brandt
Professor Abraham Kaplan
Professor Frederick Wyatt


Saracens drop appeal against salary cap punishments
Saracens will not appeal against heavy punishments for breaching Premiership's salary cap regulations, the club announced on Monday.
REUTERS: Saracens will not appeal against heavy punishments for breaching Premiership's salary cap regulations, the club announced on Monday.
The English and European champions have decided not to contest the 5.36 million pound fine and the 35-point penalty imposed for failing to disclose payments in each of the past three seasons.
A joint statement between Saracens and Premiership Rugby said that both parties had concluded matters and the league table would be updated immediately to reflect the sanctions.
"We have made mistakes and so, with humility, we must accept these penalties. As a club, we will now pull together and meet the challenges that lie ahead," Saracens chairman Nigel Wray said in a statement.
"We confirm our commitment to the salary cap, and the underlying principle of a level playing field, and will continue to work transparently with Premiership Rugby in this regard."
Saracens' current tally will be adjusted to -22, leaving them 26 points adrift of 11th-placed Leicester Tigers.
"We welcome Saracens' decision to accept the verdict of the independent panel and are pleased the club has crucially reaffirmed its commitment to the Premiership Rugby Salary Cap," said Darren Childs, chief executive of Premiership Rugby.
"This is the right outcome for English club rugby. Bringing this process to a conclusion means that we can focus on working in partnership with all clubs to continue to build a competitive and successful league."
The decision marks a change of approach for Saracens, who initially outlined their intention to challenge the ruling and said they were "shocked and disappointed by these heavy-handed sanctions".
On Monday, Wray confirmed any further appeal from Saracens would have been a "costly, time consuming and destabilising" exercise.
"We will shortly introduce robust independent governance measures acceptable to all, including the appointment to the Saracens board of a director, who will oversee a new governance regime," he added.
"I will continue as always to support the club financially going forwards to ensure there is no financial instability or uncertainty."
(Reporting by Hardik Vyas in Bengaluru; Editing by Christian Radnedge)


Personal details
Preferences
Surprise!
Personal details
Preferences
Help us surprise you!
With Halbtax
Without Halbtax
Choose trip option
City trip
Hike
Maximum time until destination
1 Hour
2 Hours
3 Hours
4 Hours
5 Hours


With our ticketing services you are able to create a variety of tickek options based on your event's needs. From free tickets to paid ones( regular, VIP, VIP+, table for 4, 6 or 8) We cover your needs. Note that you can create more than one ticket type for your event.


Bad Hair Day
问题描述 :
Some of Farmer John’s N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-conscious about her messy hairstyle, FJ wants to count the number of other cows that can see the top of other cows’ heads.
Each cow i has a specified height hi (1 ≤ hi ≤ 1,000,000,000) and is standing in a line of cows all facing east (to the right in our diagrams). Therefore, cow i can see the tops of the heads of cows in front of her (namely cows i+1, i+2, and so on), for as long as these cows are strictly shorter than cow i.
Consider this example:
=
= =
= - = Cows facing right -->
= = =
= - = = =
= = = = = =
1 2 3 4 5 6
Cow#1 can see the hairstyle of cows #2, 3, 4
Cow#2 can see no cow’s hairstyle
Cow#3 can see the hairstyle of cow #4
Cow#4 can see no cow’s hairstyle
Cow#5 can see the hairstyle of cow 6
Cow#6 can see no cows at all!
Let ci denote the number of cows whose hairstyle is visible from cow i; please compute the sum of c1 through cN.For this example, the desired is answer 3 + 0 + 1 + 0 + 1 + 0 = 5.
输入:
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i.
输出:
样例输入:
6 10 3 7 4 12 2
样例输出:
5
解题代码:
/* @author: */ (1) import java.util.Scanner; import java.util.Arrays; public class Main{ public static void main(String args[]) { Scanner sc=new Scanner(System.in); int n,i; int p[]=new int[80010],q[]=new int[80010]; n=sc.nextInt(); for(i=0;i< n;i++) p[i]=sc.nextInt(); for(i=0;i< n;i++) q[i]=1; p[n]=1000000010; for(i=n-1;i>=0;i--) { int u=p[i+1]; while(p[i]>p[i+q[i]]) q[i]+=q[i+q[i]]; } long total=0; for(i=0;i< n;i++) total+=q[i]; total-=n; System.out.printf("%d\n",total); } } (2) import java.util.Scanner; import java.util.Arrays; public class Main{ static final int maxn=80001; public static void main(String args[]) { Scanner sc=new Scanner(System.in); int h[]=new int[maxn]; int next[]=new int[maxn]; int s[]=new int[maxn]; int i, k, n; long sum; while(sc.hasNext()){ Arrays.fill(next,0); Arrays.fill(s,0); n=sc.nextInt(); for(i = 0; i < n; i++){ h[i]=sc.nextInt(); s[i] = 0; } for (i = n - 1, sum = 0; i >= 0; i--) { k = i + 1; for (; k < n && h[k] < h[i]; k = next[k]){ s[i] += s[k] + 1; } next[i] = k; sum += s[i]; } System.out.printf("%d\n", sum); } } }
有一点问题。。后面动态规划的程序中
int dp[n+1][W+1];
会报错 提示表达式必须含有常量值。该怎么修改呢。。
网站做得很好看，内容也多，全。前段时间在博客园里看到有人说：网页的好坏看字体。觉得微软雅黑的字体很好看，然后现在这个网站也用的这个字体！nice!
.net中char类型不是两个字节么
跟书上的解法不一样，不知道哪个效率要高些
这配图…..
写的很好~~
以了解 想問為甚麼 Tbl[6001] = {1} 初始化都是1
為何不是Tbl[0]=1 其他為0
找bug好专业的说
写的很好~~
简洁的代码
第一题还有个解释：没说桌子有多大，可以假设桌子和硬币一样大，肯定是先手胜
赞一个
对，就是把这32位当成一个长度为32的数
刚开始学习，为啥会报错了


Compiler
what does it do
- LLVM7.0.0 based parser generates the AST of the TU Translation Unit
- objects marked/painted with the operators are identified,
- topological reordering of dependency graph
- elimination
- code generation: HDF5 Data Description Language
- include the generated header file into your TU translation unit
- second stage: invoke your favourite compiler: intel, gcc, cray, ibm, pg, ...
Goodies
- H5CPP.CA
- LIVE DEMO: http://h5cpp.ca/cgi/redirect.py
- ami-38726547


toc: false
copyright: false
assets: none
Examples outside of clauses aren't processed specially.
This is an example.
Example Section
Examples inside clauses are numbered and have captions. Captions are optional.
Example Subclause
Multiple examples are numbered similar to notes
So this becomes example 2.


JavaScript is disabled on your browser.
Skip navigation links
Overview
Package
Class
Use
Tree
Deprecated
Index
Help
Prev Letter
Next Letter
Frames
No Frames
All Classes
A
B
C
D
E
G
I
L
M
N
O
P
R
S
T
U
V
W
P
packageRadioButton
- Variable in class com.lukas783.mdt.ui.
AddNewTaskPanel
parseChildren(String, NodeList)
- Method in class com.lukas783.mdt.api.
PomInfo
Recursively parses the nodes of an XML file into a mapping of attributes and values.
PomInfo
- Class in
com.lukas783.mdt.api
A POJO that defines an XML POM file.
PomInfo(File)
- Constructor for class com.lukas783.mdt.api.
PomInfo
Constructs a
PomInfo
object.
processButton
- Variable in class com.lukas783.mdt.ui.
ProcessPanel
ProcessButtonAction
- Class in
com.lukas783.mdt.ui.actions
Handles the action for processing tasks.
ProcessButtonAction()
- Constructor for class com.lukas783.mdt.ui.actions.
ProcessButtonAction
processOutputAppend(String)
- Method in interface com.lukas783.mdt.api.
IProcessServiceListener
A required method that is meant to be called when
ProcessService.executeProcessTasks()
finishes.
processOutputAppend(String)
- Method in class com.lukas783.mdt.ui.
ProcessPanel
A method required by
IProcessServiceListener
.
processOutputAppend(String)
- Method in class com.lukas783.mdt.ui.
TaskPanel
Required function from
IProcessServiceListener
ProcessPanel
- Class in
com.lukas783.mdt.ui
A panel to display processing information.
ProcessPanel()
- Constructor for class com.lukas783.mdt.ui.
ProcessPanel
Instantiate, build, display, and attach listeners to the panel and its components.
ProcessService
- Class in
com.lukas783.mdt.service
A singleton-service class that can be called statically by any class that needs to use it.
ProcessService()
- Constructor for class com.lukas783.mdt.service.
ProcessService
The private facing constructor used by the public-facing
ProcessService.getInstance()
method to create a new service instance reference if one does not already exist.
A
B
C
D
E
G
I
L
M
N
O
P
R
S
T
U
V
W
Skip navigation links
Overview
Package
Class
Use
Tree
Deprecated
Index
Help
Prev Letter
Next Letter
Frames
No Frames
All Classes


Jan Bouvrie
on 2012-08-08 17:15:20
Is it me, or is the type change from string '4.0' to numeric 4 in the example a side effect?
Rafa?
on 2011-09-20 08:42:35
@Paul: I changed the function, so it returns Array when preserve_keys is falsy.
https://github.com/kvz/phpjs/blob/master/functions/array/array_reverse.js
I think it was the first and last time I've touched array functions.
Paul
on 2011-09-20 02:30:55
When you pass a flat array (no direct keys) of just strings, and even set preserve_keys
to false, you of course keep getting an object returned, and not an array as tmp_arr = {}
and not tmp_arr = []
So in the case of there being no supplied keys in the array this does not seem to work.
a = ["a", "b", "c"];
b = PhpJs.array_reverse(a);
display b and you get [object Object] under QtScript at least.
Change to tmp_arr = []
... and you get the expected c, b, a
Does the function need to test on preserve_keys first as to what temp_arr
is created as?
makanaki
on 2011-02-09 17:57:12
At least when there's no flag " preserve_keys" this function should return array, not object.
Kevin van Zonneveld
on 2008-11-18 12:24:46
@ frame: Yeah php.js is by no means ready. New functions are written and bugs are being fixed. It's a good idea to update your version every once in a while.
frame
on 2008-11-18 01:38:31
hmm .. i have downloaded the lib again and now there are the missing functions included.. please ignore..
frame
on 2008-11-18 01:25:46
Some functions are not included in php.js or php.min.js.. why?
do you forget to?
ex: file_exists, array_reserve
Also...
on 2008-03-21 04:10:17
Also from the site I just mentioned, here's a function which returns a genuine array (this could probably be combined with your function to test for preserve_keys and if not present, return a genuine array?):
function array_reverse(arr) {
/* Simulate copy by value */
var arr_rev = [];
for (var i = 0; i < arr.length; i++) {
arr_rev[i] = arr[i];
}
arr_rev.reverse();
return arr_rev;
}
Brett Zamir
on 2008-03-21 03:53:29
Seems you've already done a whole lot of work, but not knowing about your site, I had started a wiki to keep this kind of information: http://javascript.wikia.com/wiki/PHP-Javascript . There are a few functions there presently, but please feel free to consider hosting this at such a wiki so it can be easily maintained by the whole community! Thanks! Email me at brettz9 & yahoo if you like.
Kevin van Zonneveld
on 2008-02-16 13:48:31
@ Karol Kowalski: That's solid work you can take pride in Karol, thank you!
Karol Kowalski
on 2008-02-12 13:40:35
Hello,
I've done some code refactoring, making the code do what it really needs to do (there's no need for the 2nd loop, it there?). I've run a test and it seems to be 38% faster. Here's the code
function array_reverse( array, preserve_keys ) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// * example 1: array_reverse( [ 'php', '4.0', ['green', 'red'] ], true );
// * returns 1: { 2: ['green', 'red'], 1: 4, 0: 'php'}
var i=0, f, key, keys = [], key_cnt=0, tmp_ar = {};
for(key in array){
keys[i++] = key;
}
keys = keys.reverse();
key_cnt = keys.length;
for( i=0; i < key_cnt; i++ ){
tmp_ar[(preserve_keys ? keys[i] : i)] = array[keys[i]];
}
return tmp_ar;
}
function array_reverse2( array, preserve_keys ) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// * example 1: array_reverse( [ 'php', '4.0', ['green', 'red'] ], true );
// * returns 1: { 2: ['green', 'red'], 1: 4, 0: 'php'}
var arr_len=array.length, newkey=0, tmp_ar = {}
for(var key in array){
newkey=arr_len-key-1;
tmp_ar[(!!preserve_keys)?newkey:key]=array[newkey]
}
return tmp_ar;
}
// wrapped in windows onload cause
// Firebug 1.1 throws an error otherwise
window.onload=function () {
console.time('array_reverse')
for (var i=10000;i;i--) {
array_reverse( [ 'php', '4.0', ['green', 'red'] ], true );
}
console.timeEnd('array_reverse')
console.time('array_reverse2')
for (var i=10000;i;i--) {
array_reverse2( [ 'php', '4.0', ['green', 'red'] ], true );
}
console.timeEnd('array_reverse2')
}


- target(MFLocationCoordinate) - Method in class vn.map4d.map.camera.MFCameraPosition.Builder
-
Set location where camera pointing at
- texture(String) - Method in class vn.map4d.map.annotations.MFBuildingOptions
-
Set texture for User Building
- tileProvider(MFTileProvider) - Method in class vn.map4d.map.overlays.MFTileOverlayOptions
-
Set the buildingProvider for Tile Overlay
- tilt(double) - Method in class vn.map4d.map.camera.MFCameraPosition.Builder
-
set tilt of camera in degrees
- title(String) - Method in class vn.map4d.map.annotations.MFMarkerOptions
-
- title(String) - Method in class vn.map4d.map.annotations.MFPOIOptions
-
Set title for UserPOI
- titleColor(int) - Method in class vn.map4d.map.annotations.MFPOIOptions
-
Set color for User POI
- touchable(boolean) - Method in class vn.map4d.map.annotations.MFBuildingOptions
-
A boolean value that determines whether user events are ignored and removed from the event queue.
- touchable(boolean) - Method in class vn.map4d.map.annotations.MFCircleOptions
-
A boolean value that determines whether user events are ignored and removed from the event queue.
- touchable(boolean) - Method in class vn.map4d.map.annotations.MFMarkerOptions
-
A boolean value that determines whether user events are ignored and removed from the event queue.
- touchable(boolean) - Method in class vn.map4d.map.annotations.MFPOIOptions
-
A boolean value that determines whether user events are ignored and removed from the event queue.
- touchable(boolean) - Method in class vn.map4d.map.annotations.MFPolygonOptions
-
A boolean value that determines whether user events are ignored and removed from the event queue.
- touchable(boolean) - Method in class vn.map4d.map.annotations.MFPolylineOptions
-
A boolean value that determines whether user events are ignored and removed from the event queue.
- TwoFingerGestureDetector - Class in vn.map4d.map.core.multitouch
-
- TwoFingerGestureDetector(Context) - Constructor for class vn.map4d.map.core.multitouch.TwoFingerGestureDetector
-
- type(String) - Method in class vn.map4d.map.annotations.MFPOIOptions
-
Set type for User POI


District of Columbia Army National Guard
May 7, 2011 . Led by a Commanding General, it is the only Army National Guard . the D.C. National Guard (DCNG) has no local jurisdiction, no matter the .
http://www.globalsecurity.org/military/agency/army/arng-dc.htm
Treatment for Herniated or Bulging Discs
District of Columbia Army National Guard - Wikipedia, the free ...
It is led by a Commanding General, and is the only Army National Guard organization . The D.C. National Guard is also unique from other National Guard .
http://en.wikipedia.org/wiki/District_of_Columbia_Army_National_Guard
Contact Us - North Carolina National Guard Home - The National ...
Before you email please view our FAQs. For web site issues, please contact our webmaster. For all other questions, please find an appropriate contact on our .
http://states.ng.mil/sites/DC/Pages/contact.aspx
dc national guard commander Herniated or Bulging Discs
DVIDS - News - DC National Guard stands ready as Hurricane ...
Oct 29, 2012 . WASHINGTON - The D.C. National Guard's Quick Reaction Force of . R. Schwartz, commanding general, District of Columbia National Guard.
http://www.dvidshub.net/news/96940/dc-national-guard-stands-ready-hurricane-sandy-approaches
news briefs ... news briefs ... news briefs
Senior Command Chief Warrant Officer. An all-hands meeting for warrant officers in the DC National Guard gave us an opportunity in April to come together .
http://ebooks.aqppublishing.com/archive/national_guard/DCGuardian.pdf
Official Impairment Listing for Spinal Disorders
DC National Guard - District of Columbia National Guard, D.C. Army ...
HOME | · PARENTS; |; MILITARY PROFESSIONALS; |; NEW SOLDIER | · OFFICERS; |; PRIOR SERVICE; |; TRAINING; |; EDUCATION · | MORE INFO .
http://www.dcnationalguard.com/
- hotel higuey punta cana (narrowing of the spine)
DVIDS - News - National Guard hosts rehearsal for 57th Presidential ...
23 hours ago . DC National Guard rehearses 57th Inauguration Support . Errol Schwartz, commanding general of the District of Columbia National Guard, .
http://www.dvidshub.net/news/99149/national-guard-hosts-rehearsal-57th-presidential-inaugurationCommanding General - North Carolina National Guard Home - The ...
Major General Errol R. Schwartz is the Commanding General, Joint Force Headquarters, District of Columbia National Guard. He is responsible for operational .
http://states.ng.mil/sites/DC/leadership/Pages/CommandingGeneral.aspx
National Guard of the United States - Wikipedia, the free encyclopedia
National Guard members are a subset of the Militia as defined by 10 U.S.C. . is routinely delegated to the Commanding General of the DC National Guard.
http://en.wikipedia.org/wiki/National_Guard_of_the_United_States
District of Columbia National Guard "The Capital ... - ngadc.net
The DC National Guard (DCNG), established in 1802, is unique among Guard units . within a state or territory where the governor is the Commander-in-Chief.
http://ngadc.net/documents/DCNG_Background_Paper_2010.pdf
Medical-Vocational Allowance for Herniated Disc
District of Columbia National Guard - Wikipedia, the free encyclopedia
D.C. Armory - Washington, D.C..jpg . The District of Columbia National Guard is the branch of the United States National Guard based in Washington, D.C.. . The President of the United States is the Commander in Chief of the National Guard .
http://en.wikipedia.org/wiki/District_of_Columbia_National_Guard
Retired Guard commander killed in D.C. crash - Army News | News ...
Jun 23, 2009 . From July 2003 until his retirement in 2008, Wherley was commanding general of Joint Force Headquarters, D.C. National Guard, where he .
http://www.armytimes.com/news/2009/06/army_train_victim_062309w/
Appealing a Denial of Benefits
DC National Guard
Freedom Salute Ceremony Honors Recently Deployed Soldiers · Combined Federal Campaign kick-off even · Kiowa · Air National Guard Command Chief Urges .
http://www.dc.ng.mil/
DVIDS - News - DC National Guard aids local authorities in the ...
Oct 30, 2012 . Errol R. Schwartz, Commanding General of the D.C. National Guard, and Kenneth Ellerbe, D.C. Chief of Fire and EMS during a storm damage .
http://www.dvidshub.net/news/97023/dc-national-guard-aids-local-authorities-aftermath-hurricane-sandy


Magma Gems
With this real-time project, my job was to create the crystal material using Substance Painter and Designer and the Unreal Engine 4. I used Substance Designer to create the base surface textures for use with Unreal's node-based material Blueprints in order to create a parent crystal material with various inputs for changing color, emission, magma crust, etc. to individualize each crystal instance.
Part 1 : Creating a Substance Using Substance Designer
Using various noise textures to create a rock-like pattern
Accentuating the existing veining for coloring in Unreal
×
Part 2 : Building the texture in Unreal
The entire node tree in Unreal
The BumpOffset node was used to push the interior facets texture deeper in the mesh.
Using the original texture, I masked out areas that would give the appearence of magma "encrusted" on the exterior of the crystal
Gem Instance with only changing the base color
Testing the material instance and the bumpoffset effect that 'pushes' the interior facet texture deeper in the mesh
Gem instance with the 'magma crust' input on and changing the UV scale of the interior facet texture
The finished pink crystal instance and all available input options
The blue crystal instance and all available input options
Final Render


An encyclopedic atlas of history and happenings that anyone can edit.
Add to the Map...
Add a Time Space Map event
| Where e.g., Gettysburg, PA | When e.g., 1962; Oct 14,1066; 1880-1886 | What e.g., Battle | |
| Where e.g., Gettysburg, PA | When e.g., 1962; Oct 14,1066; 1880-1886 | What e.g., Battle | |
An Atlas of History and HappeningsTime Space Map is an encyclopedic, online atlas of history and happenings that anyone can edit; a geographic wiki. You can search, add or edit, view or undo changes, discuss, watch, tag, or flag for removal. Recently Added
|


Location & Schedule
Liberty Two, 32nd Floor - 50 South 16th St. Philadelphia, PA 19102
February 21, 2012
Presentations: 6pm - 9pm
Open Bar: 9:30pm - 11:30pm
--- layout: default title: Home ---
{% for post in site.posts %} {% include post_template.html %} {% endfor %}


Construct a new layout item.
The widget to be managed by the item.
The widget will be set to absolute positioning.
The widget managed by the layout item.
Whether the managed widget is attached.
Whether the layout item is disposed.
Whether the managed widget is hidden.
Whether the managed widget is visible.
The computed maximum height of the widget.
This value can be updated by calling the fit
method.
The computed maximum width of the widget.
This value can be updated by calling the fit
method.
The computed minimum height of the widget.
This value can be updated by calling the fit
method.
The computed minimum width of the widget.
This value can be updated by calling the fit
method.
Dispose of the the layout item.
This will reset the positioning of the widget.
Update the computed size limits of the managed widget.
Update the position and size of the managed widget.
The left edge position of the layout box.
The top edge position of the layout box.
The width of the layout box.
The height of the layout box.
Generated using TypeDoc
An object which assists in the absolute layout of widgets.
Notes
This class is useful when implementing a layout which arranges its widgets using absolute positioning.
This class is used by nearly all of the built-in Phosphor layouts.


Defining New TIFF Tags
Libtiff has built-in knowledge of all the standard TIFF tags, as
well as extensions. The following describes how to add knowledge of
new tags as builtins to libtiff, or how to application specific tags can
be used by applications without modifying libtiff.
TIFFFieldInfo
How libtiff manages specific tags is primarily controlled by the
definition for that tag value stored internally as a TIFFFieldInfo structure.
This structure looks like this:
typedef struct {
ttag_t field_tag; /* field's tag */
short field_readcount; /* read count / TIFF_VARIABLE / TIFF_VARIABLE2 / TIFF_SPP */
short field_writecount; /* write count / TIFF_VARIABLE / TIFF_VARIABLE2 */
TIFFDataType field_type; /* type of associated data */
unsigned short field_bit; /* bit in fieldsset bit vector */
unsigned char field_oktochange;/* if true, can change while writing */
unsigned char field_passcount;/* if true, pass dir count on set */
char *field_name; /* ASCII name */
} TIFFFieldInfo;
- field_tag: the tag number. For instance 277 for the
SamplesPerPixel tag. Builtin tags will generally have a #define in
tiff.h for each known tag.
- field_readcount: The number of values which should be read.
The special value TIFF_VARIABLE (-1) indicates that a variable number of
values may be read. The special value TIFFTAG_SPP (-2) indicates that there
should be one value for each sample as defined by TIFFTAG_SAMPLESPERPIXEL.
The special value TIFF_VARIABLE2 (-3) is similar to TIFF_VARIABLE
but the required TIFFGetField() count value must be uint32_t* instead of uint16_t* as for TIFF_VARIABLE (-1).
For ASCII fields with variable length, this field is TIFF_VARIABLE.
- field_writecount: The number of values which should be written.
Generally the same as field_readcount. A few built-in exceptions exist, but
I haven't analysed why they differ.
- field_type: Type of the field. One of TIFF_BYTE, TIFF_ASCII,
TIFF_SHORT, TIFF_LONG, TIFF_RATIONAL, TIFF_SBYTE, TIFF_UNDEFINED,
TIFF_SSHORT, TIFF_SLONG, TIFF_SRATIONAL, TIFF_FLOAT, TIFF_DOUBLE or
TIFF_IFD. Note that some fields can support more than one type (for
instance short and long). These fields should have multiple TIFFFieldInfos.
- field_bit: Built-in tags stored in special fields in the
TIFF structure have assigned field numbers to distinguish them (ie.
FIELD_SAMPLESPERPIXEL). New tags should generally just use
FIELD_CUSTOM indicating they are stored in the generic tag list.
- field_oktochange: TRUE if it is OK to change this tag value
while an image is being written. FALSE for stuff that must be set once
and then left unchanged (like ImageWidth, or PhotometricInterpretation for
instance).
- field_passcount: If TRUE, then the count value must be passed
in TIFFSetField(), and TIFFGetField(), otherwise the count is not required.
This should generally be TRUE for non-ascii variable count tags unless
the count is implicit (such as with the colormap).
- field_name: A name for the tag. Normally mixed case (studly caps)
like "StripByteCounts" and relatively short.
A TIFFFieldInfo definition exists for each built-in tag in the tif_dirinfo.c
file. Some tags which support multiple data types have more than one
definition, one per data type supported.
Various functions exist for getting the internal TIFFFieldInfo definitions,
including _TIFFFindFieldInfo(), and _TIFFFindFieldInfoByName(). See
tif_dirinfo.c for details. There must be some mechanism to get the whole
list, though I don't see it off hand.
Default Tag Auto-registration
In libtiff 3.6.0 a new mechanism was introduced allowing libtiff to
read unrecognised tags automatically. When an unknown tags is encountered,
it is automatically internally defined with a default name and a type
derived from the tag value in the file. Applications only need to predefine
application specific tags if they need to be able to set them in a file, or
if particular calling conventions are desired for TIFFSetField() and
TIFFGetField().
When tags are autodefined like this the field_readcount and
field_writecount values are always TIFF_VARIABLE2 (-3). The
field_passcount is always TRUE, and the field_bit is
FIELD_CUSTOM. The field name will be "Tag %d" where the %d is the tag
number.
Thus, to read anonymous auto-registered tags use the following:
uint32_t count;
void* value; //has to be a pointer to the expected value type.
TIFFGetField(tif, TIFFTAG_UNKNOWN_TO_LIBTIFF, &count, &value);
Defining Application Tags
For various reasons, it is common for applications to want to define
their own tags to store information outside the core TIFF specification.
This is done by calling TIFFMergeFieldInfo() with one or more TIFFFieldInfos.
The libgeotiff library provides geospatial information extensions within
a TIFF file. First, a set of TIFFFieldInfo's is prepared with information
on the new tags:
static const TIFFFieldInfo xtiffFieldInfo[] = {
/* XXX Insert Your tags here */
{ TIFFTAG_GEOPIXELSCALE, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
TRUE, TRUE, "GeoPixelScale" },
{ TIFFTAG_GEOTRANSMATRIX, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
TRUE, TRUE, "GeoTransformationMatrix" },
{ TIFFTAG_GEOTIEPOINTS, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
TRUE, TRUE, "GeoTiePoints" },
{ TIFFTAG_GEOKEYDIRECTORY, -1,-1, TIFF_SHORT, FIELD_CUSTOM,
TRUE, TRUE, "GeoKeyDirectory" },
{ TIFFTAG_GEODOUBLEPARAMS, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
TRUE, TRUE, "GeoDoubleParams" },
{ TIFFTAG_GEOASCIIPARAMS, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
TRUE, FALSE, "GeoASCIIParams" }
};
In order to define the tags, we call TIFFMergeFieldInfo() on the
desired TIFF handle with the list of TIFFFieldInfos.
#define N(a) (sizeof (a) / sizeof (a[0]))
/* Install the extended Tag field info */
TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
The tags need to be defined for each TIFF file opened - and when reading
they should be defined before the tags of the file are read, yet a valid
TIFF * is needed to merge the tags against. In order to get them
registered at the appropriate part of the setup process, it is necessary
to register our merge function as an extender callback with libtiff.
This is done with TIFFSetTagExtender(). We also keep track of the
previous tag extender (if any) so that we can call it from our extender
allowing a chain of customizations to take effect.
static TIFFExtendProc _ParentExtender = NULL;
static
void _XTIFFInitialize(void)
{
static int first_time=1;
if (! first_time) return; /* Been there. Done that. */
first_time = 0;
/* Grab the inherited method and install */
_ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
}
The extender callback is looks like this. It merges in our new fields
and then calls the next extender if there is one in effect.
static void
_XTIFFDefaultDirectory(TIFF *tif)
{
/* Install the extended Tag field info */
TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
/* Since an XTIFF client module may have overridden
* the default directory method, we call it now to
* allow it to set up the rest of its own methods.
*/
if (_ParentExtender)
(*_ParentExtender)(tif);
}
The above approach ensures that our new definitions are used when reading
or writing any TIFF file. However, since on reading we already have
default definitions for tags, it is usually not critical to pre-define them.
If tag definitions are only required for writing custom tags, you can just
call TIFFMergeFieldInfo() before setting new tags. The whole extender
architecture can then be avoided.
A similar approach is taken to the above. However, the TIFFFieldInfo
should be added to the tiffFieldInfo[] list in tif_dirinfo.c. Ensure that
new tags are added in sorted order by the tag number.
Normally new built-in tags should be defined with FIELD_CUSTOM; however, if
it is desirable for the tag value to have it's own field in the TIFFDirectory
structure, then you will need to #define a new FIELD_ value for it, and
add appropriate handling as follows:
- Define the tag in tiff.h.
- Add a field to the directory structure in tif_dir.h
and define a FIELD_* bit (also update the definition of
FIELD_CODEC to reflect your addition).
- Add an entry in the TIFFFieldInfo array defined at the top of
tif_dirinfo.c.
Note that you must keep this array sorted by tag
number and that the widest variant entry for a tag should come
first (e.g. LONG before SHORT).
- Add entries in _TIFFVSetField() and _TIFFVGetField()
for the new tag.
- (optional) If the value associated with the tag is not a scalar value
(e.g. the array for TransferFunction) and requires
special processing,
then add the appropriate code to TIFFReadDirectory() and
TIFFWriteDirectory(). You're best off finding a similar tag and
cribbing code.
- Add support to TIFFPrintDirectory() in tif_print.c
to print the tag's value.
If you want to maintain portability, beware of making assumptions
about data types. Use the typedefs (uint16_t, etc. when dealing with
data on disk and t*_t when stuff is in memory) and be careful about
passing items through printf or similar vararg interfaces.
To add tags that are meaningful only when a particular compression
algorithm is used follow these steps:
- Define the tag in tiff.h.
- Allocate storage for the tag values in the private state block of
the codec.
- Insure the state block is created when the codec is initialized.
- At TIFFInitfoo time override the method pointers in the
TIFF structure
for getting, setting and printing tag values. For example,
sp->vgetparent = tif->tif_vgetfield;
tif->tif_vgetfield = fooVGetField; /* hook for codec tags */
sp->vsetparent = tif->tif_vsetfield;
tif->tif_vsetfield = fooVSetField; /* hook for codec tags */
tif->tif_printdir = fooPrintDir; /* hook for codec tags */
(Actually you may decide not to override the
tif_printdir method, but rather just specify it).
- Create a private TIFFFieldInfo array for your tags and
merge them into the core tags at initialization time using
_TIFFMergeFieldInfo; e.g.
_TIFFMergeFieldInfo(tif, fooFieldInfo, N(fooFieldInfo));
(where N is a macro used liberaly throughout the distributed code).
- Fill in the get and set routines. Be sure to call the parent method
for tags that you are not handled directly. Also be sure to set the
FIELD_* bits for tags that are to be written to the file. Note that
you can create ``pseudo-tags'' by defining tags that are processed
exclusively in the get/set routines and never written to file (see
the handling of TIFFTAG_FAXMODE in tif_fax3.c
for an example of this).
- Fill in the print routine, if appropriate.
Note that space has been allocated in the FIELD_* bit space for
codec-private tags. Define your bits as FIELD_CODEC+<offset> to
keep them away from the core tags. If you need more tags than there
is room for, just increase FIELD_SETLONGS at the top of
tiffiop.h.
Last updated: $Date: 2016-09-25 20:05:44 $


Occasionally a computation can only be made once data is retrieved (messages are received) from two or more different data sources. For example, you can't tell whether you won the lottery until you've got your ticket number and the winning number. You can't make change for a purchase until you know the price and the amount tendered.
Rholang has the join operator for exactly this situation.
A space exploration company wants to make sure their rocket only launches when both of two flight engineers, Alice and Bob, give the launch command. As an example, Bob would give the go ahead by sending @"BobLaunch"!("launch")
.
When both engineers give the command, the rocket can be launched. Consider how this code might be written using the join operator that you just learned about.
You may have been tempted to solve the rocket problem by first receiving one then the other.
The problem here is when Alice okay's the launch, but Bob hasn't yet. Alice should be able to change her mind, but she cannot. Imagine if she suddenly noticed a problem with the rocket, or received some bad news and wanted to abort the launch.
When using a join, she can still change her mind because the for
won't consume her launch message until Bob's message also appears and is ready to be consumed.
EXERCISE: Write the code that Alice would need to "par in" and retract her launch command.
In the simplest case, Alice sould simply par in a receive to take her launch message out of the tupplespace.
for (x <- @"AliceLaunch"){0}
The concept of joins is framed as the dining philosophers problem, and explored further in the official rholang tutorial.
Another way that Alcie could retract her launch command is by leaving herself an abort button when she actually sends the launch command. At the moment this solution may seem round-about compared to the previous solution. But once we learn about unforgeable names and object capabilities, it may make more sense.
for (x <- y; a <- b){ 0 }
, which channel must be sent on first?
y, b, doesn't matter, they must be sent simultaneously.
In for (x <- y; a <- b){ 0 }
, which message will be consumed first?
y, b, doesn't matter, they will be consumed simultaneously.
Why did alice have to send the message "abort"?
Because she was aborting the launch
Because the channel was called @"AliceAbort"
She didn't; any message would have done
There is a game where two players will each send a message on seperate channels. Whoever sends the first message, loses, and whoever sends the second message wins. Your task here is to write the game code that will tell which player won. To play the game, players should send messages like shown.
In this case we actually don't want to double for because we care which player went first. Hope I didn't trick you ;)
Like the comment says, you should send the messages in both orders to make sure of who wins. The easiest way to do that right now is probably in the REPL. Another option is to have one player signal the other for when to go as shown below. We'll explore this concept further in the next unit.


Navigation menu with a login form and a submit button inside of it.
Resize the browser window to see the responsive effect.