Download big file is too slow - java

I am encountering with a scenario like this.
My project receives a download request from perl
void downloadRequest(FileItemIterator items,
HttpServletResponse response) throws Exception
{
log.info("Start downloadRequest.......");
OutputStream os = response.getOutputStream();
File file = new File("D:\\clip.mp4");
FileInputStream fileIn = new FileInputStream(file);
//while ((datablock = dataOutputStreamServiceImpl.readBlock()) != null)
byte[] outputByte = new byte[ONE_MEGABYE];
while (fileIn.read(outputByte) != -1)
{
System.out.println("--------" + (i = i + 1) + "--------");
System.out.println(new Date());
//dataContent = datablock.getContent();
System.out.println("Start write " + new Date());
os.write(outputByte);
System.out.println("End write " + new Date());
//System.out.println("----------------------");
}
os.close();
}
}
I try to read and write blocks of 1MB from the file. However, it takes too long for downloading the whole file. ( my case is 20mins for file of 100MB)
I try to sysout and I saw a result like this:
The first few blocks can read, write data realy fast:
--------1--------
Mon Dec 07 16:24:20 ICT 2015
Start write Mon Dec 07 16:24:20 ICT 2015
End write Mon Dec 07 16:24:21 ICT 2015
--------2--------
Mon Dec 07 16:24:21 ICT 2015
Start write Mon Dec 07 16:24:21 ICT 2015
End write Mon Dec 07 16:24:21 ICT 2015
--------3--------
Mon Dec 07 16:24:21 ICT 2015
Start write Mon Dec 07 16:24:21 ICT 2015
End write Mon Dec 07 16:24:21 ICT 2015
But the next block is slower than the previous
--------72--------
Mon Dec 07 16:29:22 ICT 2015
Start write Mon Dec 07 16:29:22 ICT 2015
End write Mon Dec 07 16:29:29 ICT 2015
--------73--------
Mon Dec 07 16:29:29 ICT 2015
Start write Mon Dec 07 16:29:29 ICT 2015
End write Mon Dec 07 16:29:37 ICT 2015
--------124--------
Mon Dec 07 16:38:22 ICT 2015
Start write Mon Dec 07 16:38:22 ICT 2015
End write Mon Dec 07 16:38:35 ICT 2015
--------125--------
Mon Dec 07 16:38:35 ICT 2015
Start write Mon Dec 07 16:38:35 ICT 2015
End write Mon Dec 07 16:38:48 ICT 2015
I realy cannot understand how the outputStream write, why it take such a long time like that? or I made some mistakes?
Sorry for my bad english. I realy need your support. Thank in advance!

There is no guaranty that the read(byte[] b) method will read b.length number of bytes from the file which mean that your code could be sending more bytes then the file actually has.
For example, if you're processing a 10 MB file and the read(byte[] b) always reads b.length/2 from the file, you will be sending 20 MB.
To address that, you could do something like this.
byte[] outputByte = new byte[ONE_MEGABYE];
int r = -1;
while ((r = fileIn.read(outputByte)) != -1){
os.write(outputByte,0,r);
}
This will ensure that you'll be sending only as much bytes as there were read from the file.
Beside this issue, the speed can be influenced by a lot of other factors like the internet speed or the other program's implementation.

Related

Java Date - Leap year - strange behavior

So I've got this kind of strange problem with Java's Date.
The entry-point for this problem are 2 String dates startDate("30 Jan 2016") and endate ""29 Jan 2017".
The problem is a little bit more complex,but I've summed it up just to this case.
What I have to do is get an 1 year schedule exactly like the one from bellow starting with this data.
The table contains for each month: first day, last day, and days between those 2 days.
Expected results:
/**
Sat Jan 30 00:00:00 GMT 2016 - Sun Feb 28 23:59:59 GMT 2016 - 30
Mon Feb 29 00:00:00 GMT 2016 - Tue Mar 29 23:59:59 BST 2016 - 30
Wed Mar 30 00:00:00 BST 2016 - Fri Apr 29 23:59:59 BST 2016 - 31
Sat Apr 30 00:00:00 BST 2016 - Sun May 29 23:59:59 BST 2016 - 30
Mon May 30 00:00:00 BST 2016 - Wed Jun 29 23:59:59 BST 2016 - 31
Thu Jun 30 00:00:00 BST 2016 - Fri Jul 29 23:59:59 BST 2016 - 30
Sat Jul 30 00:00:00 BST 2016 - Mon Aug 29 23:59:59 BST 2016 - 31
Tue Aug 30 00:00:00 BST 2016 - Thu Sep 29 23:59:59 BST 2016 - 31
Fri Sep 30 00:00:00 BST 2016 - Sat Oct 29 23:59:59 BST 2016 - 30
Sun Oct 30 00:00:00 BST 2016 - Tue Nov 29 23:59:59 GMT 2016 - 31
Wed Nov 30 00:00:00 GMT 2016 - Thu Dec 29 23:59:59 GMT 2016 - 30
Fri Dec 30 00:00:00 GMT 2016 - Sun Jan 29 23:59:59 GMT 2017 - 31
*/
My results are
Sat Jan 30 00:00:00 EET 2016 ::::: Sun Feb 28 23:59:59 EET 2016 ::::: 29
Mon Feb 29 00:00:00 EET 2016 ::::: Mon Mar 28 23:59:59 EEST 2016 ::::: 28
Tue Mar 29 00:00:00 EEST 2016 ::::: Thu Apr 28 23:59:59 EEST 2016 ::::: 30
Fri Apr 29 00:00:00 EEST 2016 ::::: Sat May 28 23:59:59 EEST 2016 ::::: 29
Sun May 29 00:00:00 EEST 2016 ::::: Tue Jun 28 23:59:59 EEST 2016 ::::: 30
Wed Jun 29 00:00:00 EEST 2016 ::::: Thu Jul 28 23:59:59 EEST 2016 ::::: 29
Fri Jul 29 00:00:00 EEST 2016 ::::: Sun Aug 28 23:59:59 EEST 2016 ::::: 30
Mon Aug 29 00:00:00 EEST 2016 ::::: Wed Sep 28 23:59:59 EEST 2016 ::::: 30
Thu Sep 29 00:00:00 EEST 2016 ::::: Fri Oct 28 23:59:59 EEST 2016 ::::: 29
Sat Oct 29 00:00:00 EEST 2016 ::::: Mon Nov 28 23:59:59 EET 2016 ::::: 31
Tue Nov 29 00:00:00 EET 2016 ::::: Wed Dec 28 23:59:59 EET 2016 ::::: 29
Thu Dec 29 00:00:00 EET 2016 ::::: Sat Jan 28 23:59:59 EET 2017 ::::: 30
So I’m not sure if this happens because of the February month or because 2016 was a leap year that included 29th of February.
What am I missing? I have the same problem run multiple test cases and all others are OK, but this.
I've also tried to do this with Javas 8 LocalDate and LocalDateTime and I get the exactly same results.
Here is my code
import org.apache.commons.lang.time.DateUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Main {
public static void main(String[] args) throws ParseException {
String startDate = "30 Jan 2016";
String endDate = "29 Jan 2017"; // current not using this ?!
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy");
Date start = formatter.parse(startDate);
List<Item> items = new ArrayList<>();
for (int i = 0; i < 12; i++) {
Date end = DateUtils.addMonths(start, 1);
end = DateUtils.addSeconds(end, -1);
items.add(new Item(start, end));
start = DateUtils.addMonths(start, 1);
}
items.forEach(item -> {
System.out.println(item.getStart() + " ::::: " + item.getEnd() + " ::::: " + getDifferenceDays(item.getStart(), item.getEnd()));
});
}
public static long getDifferenceDays(Date d1, Date d2) {
return ChronoUnit.DAYS.between(d1.toInstant(), d2.toInstant());
}
}
Item Class
import java.util.Date;
public class Item {
Date start;
Date end;
public Item(Date start, Date end) {
this.start = start;
this.end = end;
}
public Date getStart() {
return start;
}
public void setStart(Date start) {
this.start = start;
}
public Date getEnd() {
return end;
}
public void setEnd(Date end) {
this.end = end;
}
#Override
public String toString() {
return "Item{" +
"start=" + start +
", end=" + end +
'}';
}
}
java.time
Since you can use java.time, the modern Java date and time API, I recommend that you stick to that and leave the old classes SimpleDateFormat and Date alone. Then you also don’t need the Apache DateUtils. The ChronoUnit enum is from java.time.
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("d MMM u", Locale.ENGLISH);
String startDateString = "30 Jan 2016";
LocalDate originalStartDate
= LocalDate.parse(startDateString, dateFormatter);
for (int i = 0; i < 12; i++) {
LocalDate startDate = originalStartDate.plusMonths(i);
LocalDate nextStartDate = originalStartDate.plusMonths(i + 1);
LocalDate endDate = nextStartDate.minusDays(1);
long differenceDays = ChronoUnit.DAYS.between(startDate, nextStartDate);
System.out.format("%s - %s : %d%n", startDate, endDate, differenceDays);
}
Output is:
2016-01-30 - 2016-02-28 : 30
2016-02-29 - 2016-03-29 : 30
2016-03-30 - 2016-04-29 : 31
2016-04-30 - 2016-05-29 : 30
2016-05-30 - 2016-06-29 : 31
2016-06-30 - 2016-07-29 : 30
2016-07-30 - 2016-08-29 : 31
2016-08-30 - 2016-09-29 : 31
2016-09-30 - 2016-10-29 : 30
2016-10-30 - 2016-11-29 : 31
2016-11-30 - 2016-12-29 : 30
2016-12-30 - 2017-01-29 : 31
What went wrong in your code?
There are a couple of reasons behind your observed unexpected results.
When you add a month to January 30, you get February 29 as you had expected. In a non-leap year you would have got February 28. When you add another month to February 29, you get March 29. Is it surprising when you think about it? In a non-leap year you would have got March 28, so 2016 being a leap year actually helped you get closer to your desired result. In my code I solve this problem by adding the correct number of months to the original start date rather than adding one month to the previous start date.
As PeterMmm already said, ChronoUnit.DAYS.Between() counts full 24 hours days. Any partial day is discarded. Even 23 hours 59 minutes 59 seconds. From Sat Jan 30 00:00:00 EET 2016 to Sun Feb 28 23:59:59 EET 2016 is 30 days 23 hours 59 minutes 59 seconds, so the result you get is 30 days. In my code I solve the problem by counting the days until the start of the next item.
As an aside: From Mon Feb 29 00:00:00 EET 2016 to Mon Mar 28 23:59:59 EEST 2016, because of transistion to summer time (DST) is only 28 days 22 hours 59 minutes 59 seconds. So abstaining from subtracting a second would not solve your problem in this case.
This
end = DateUtils.addSeconds(end, -1);
isn't necessary. Or do
end = DateUtils.addSeconds(end, 0);
have a look at between() documentation.
Second parameter is exclusive. That means, your second parameter does not reach the end of day and so a day less is counted (only full 24h days are counted).
Here's a slightly different approach:
LocalDate startDate = LocalDate.of(2016, 1, 30);
LocalDate endDate = LocalDate.of(2017, 1, 30);
Function<YearMonth, LocalDate> addMonthFunction = ym -> ym
.atDay(Math.min(startDate.getDayOfMonth(), ym.lengthOfMonth()));
long months = ChronoUnit.MONTHS.between(startDate, endDate);
YearMonth yearMonth = YearMonth.from(startDate);
Stream.iterate(yearMonth, ym -> ym.plusMonths(1))
.limit(months)
.map(addMonthFunction)
.map(LocalDate::atStartOfDay)
.map(date -> {
LocalDateTime end = addMonthFunction.apply(YearMonth.from(date.plusMonths(1)))
.atStartOfDay()
.minusSeconds(1);
long between = ChronoUnit.DAYS.between(date, end) + 1;
return String.format("%s to %s (%s days)", date, end, between);
})
.forEach(System.out::println);
The idea is that each next date always falls on the 30th day of the month (or, more precisely, the same day-of-month as the start date), except if that would be an invalid date.
I used LocalDates here, but you could make it timezone-sensitive by using ZonedDateTime.

Increment and print all days in a month

I have started writing some code and need to print all the dates in a month, I can do this by adding one each day but there must be a shorter way that I am missing. This is my code so far.
I am aware that it is not the prettiest and I am wondering how to print the date while it increments for each day in January without having to constantly add 1 each time then println each time.
public static void main(String [] args) {
Calendar calendar = Calendar.getInstance()
calendar.set.(Integer.parseInt(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]));
System.out.println(calendar.getTime());
calendar.add(Calendar.DATE, 1);
System.out.println(calendar.getTime());
}
}
simple exmple using Java 8 Local date, asuming input as in the question
import java.time.LocalDate;
public class Test
{
public static void main(String[] args)
{
LocalDate ld = LocalDate.of(Integer.parseInt(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]));
do {
System.out.println(ld.toString());
ld = ld.plusDays(1);
} while (ld.getDayOfMonth() > 1); // arive at 1st of next month
}
}
Here's a simple example that prints all the days in the month. The time parts have been set to zero.
Here, we printed all the days in March 2016.
Tue Mar 01 00:00:00 MST 2016
Wed Mar 02 00:00:00 MST 2016
Thu Mar 03 00:00:00 MST 2016
Fri Mar 04 00:00:00 MST 2016
Sat Mar 05 00:00:00 MST 2016
Sun Mar 06 00:00:00 MST 2016
Mon Mar 07 00:00:00 MST 2016
Tue Mar 08 00:00:00 MST 2016
Wed Mar 09 00:00:00 MST 2016
Thu Mar 10 00:00:00 MST 2016
Fri Mar 11 00:00:00 MST 2016
Sat Mar 12 00:00:00 MST 2016
Sun Mar 13 00:00:00 MST 2016
Mon Mar 14 00:00:00 MDT 2016
Tue Mar 15 00:00:00 MDT 2016
Wed Mar 16 00:00:00 MDT 2016
Thu Mar 17 00:00:00 MDT 2016
Fri Mar 18 00:00:00 MDT 2016
Sat Mar 19 00:00:00 MDT 2016
Sun Mar 20 00:00:00 MDT 2016
Mon Mar 21 00:00:00 MDT 2016
Tue Mar 22 00:00:00 MDT 2016
Wed Mar 23 00:00:00 MDT 2016
Thu Mar 24 00:00:00 MDT 2016
Fri Mar 25 00:00:00 MDT 2016
Sat Mar 26 00:00:00 MDT 2016
Sun Mar 27 00:00:00 MDT 2016
Mon Mar 28 00:00:00 MDT 2016
Tue Mar 29 00:00:00 MDT 2016
Wed Mar 30 00:00:00 MDT 2016
Thu Mar 31 00:00:00 MDT 2016
This code will work with Java 6, Java 7, and Java 8.
package com.ggl.testing;
import java.util.Calendar;
public class PrintMonth {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
if (args.length == 2) {
int year = Integer.parseInt(args[0]);
int month = Integer.parseInt(args[1]);
calendar.set(year, month, 1);
}
int month = calendar.get(Calendar.MONTH);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
while (calendar.get(Calendar.MONTH) == month) {
System.out.println(calendar.getTime());
calendar.add(Calendar.DATE, 1);
}
}
}
public static void main(String[] args) {
LocalDate date = LocalDate.of(Integer.parseInt(args[0]), Integer.parseInt(args[1]), 1);
for (int i = 0; i < date.lengthOfMonth(); i++) {
System.out.println(date);
date = date.plusDays(1);
}
}
This is a working example:
https://github.com/OpenGamma/OG-Platform/blob/master/projects/OG-Util/src/main/java/com/opengamma/util/time/LocalDateRange.java#L113
public static LocalDateRange of(LocalDate startDateInclusive, LocalDate endDate, boolean endDateInclusive) {
ArgumentChecker.notNull(startDateInclusive, "startDate");
ArgumentChecker.notNull(endDate, "endDate");
if (endDateInclusive == false && endDate.isBefore(LocalDate.MAX)) {
endDate = endDate.minusDays(1);
}
if (endDate.isBefore(startDateInclusive)) {
throw new IllegalArgumentException("Start date must be on or after end date");
}
return new LocalDateRange(startDateInclusive, endDate);
}
How about this example?:
#JRubyMethod(name = {"asctime", "ctime"})
public RubyString asctime() {
DateTimeFormatter simpleDateFormat;
if (dt.getDayOfMonth() < 10) {
simpleDateFormat = ONE_DAY_CTIME_FORMATTER;
} else {
simpleDateFormat = TWO_DAY_CTIME_FORMATTER;
}
String result = simpleDateFormat.print(dt);
return getRuntime().newString(result);
}
Full source here: http://code.openhub.net/file?fid=VJqxO5av-KgtoQFAp9juIzamnTc&cid=KOJoiAJBzj4&s=Increment%20and%20print%20all%20days%20in%20a%20month&pp=0&fl=Java&ff=1&filterChecked=true&fp=144796&mp,=1&ml=0&me=1&md=1&projSelected=true#L0

How do I retrieve the reference number of an array in Java?

I would like to print something like this once I have my array finished:
Leg_______Departure Time_______Origin_____Destination________Travel Time
1..................(time).............................(place).........(place)........................(time)
2..................(time).............................(place).........(place)........................(time)
3..................(time).............................(place).........(place)........................(time)
I want to print out the array with automatically assigned numeric values based on the order that the user inputs the array item. I have a good idea on how to print out the array objects (time, places) but I do not know how to print out the reference number that would correspond. How would I go about making these numbers? (the dots are just placeholders and shouldnt appear in code. Id like to just float it in columns. SO doesnt let me place empty paces)
I thought I could ask the user for a location and track that item to a reference and add that reference to the the array, but that makes the numeric order static and I want them in order. Any help would be well appreciated. Thank you.
Based on what you've provided, a simple implementation is:
List <FlightDetails> flightDetails = new ArrayList<>();
for (FlightDetails aflightDetail : flightDetails) {
System.out.println(aflightDetail.getDepartureTime() + " " +
aflightDetail.getOrigin() //and so on;
}
where FlightDetails is a class holding your various attributes:
class FlightDetails {
private long departureTime;
private String origin;
//and so on, with various getters/setters
}
The for statement will print the items in the order they were inserted, since an ArrayList preserves that. Furthermore, you can also find out the 5th inserted element by simply doing a
flightDetails.get(5);
__
If you're looking for ordering based on insertion as well as access times (So that when you access a flight, it gets put to the top of the list), you can use a LinkedHashMap. This link talks in depth about it.
No need to ask user and track or map sequence. Print the sequence as the list is sorted.
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
public class SequenceOfArray
{
// Declare an ArrayList of Travel
ArrayList<Travel> travelList = new ArrayList<Travel>();
public static void main(String[] args)
{
SequenceOfArray s = new SequenceOfArray();
s.addInput(0, 4); // add non sequentional input , so that sorting by departTime gives different sequenc
s.addInput(10, 15);
s.addInput(5, 9);
s.travelList.sort(s.compareByDepartTime); // sort travel by departTime
s.print();
s.travelList.sort(s.compareById); // sort by id
s.print();
}
public void print()
{
System.out.println("id_______Leg______________Departure Time___________________________Origin_________Destination_____________Travel Time");
for (int i = 0; i < travelList.size(); i++)
{
Travel t = travelList.get(i);
// print travel, leg is dynamic, as your list is sorted.
System.out.println(t.id + ".........." + i + ".................." + t.departTime + "........" + t.origin + "........." + t.destination + ".............." + t.departTime);
}
}
Comparator<Travel> compareByDepartTime = new Comparator<Travel>()
{
#Override
public int compare(Travel o1, Travel o2)
{
return o1.departTime.compareTo(o2.departTime);
}
};
Comparator<Travel> compareById = new Comparator<Travel>()
{
#Override
public int compare(Travel o1, Travel o2)
{
int i = 0;
if (o1.id - o2.id > 0)
return 1;
if (o1.id - o2.id < 0)
return -1;
return i;
}
};
public void addInput(int start, int end)
{
for (int i = start; i < end; i++)
{
Travel t = new Travel();
t.id = i;
t.departTime = Calendar.getInstance().getTime();
t.origin = "Origin" + (i + 1);
t.destination = "Destination" + (i + 1);
t.travelTime = Calendar.getInstance().getTime();
travelList.add(t);
}
}
}
class Travel
{
long id;
Date departTime;
String origin;
String destination;
Date travelTime;
// getters and setters
}
Sample output:
id_______Leg______________Departure Time___________________________Origin_________Destination_____________Travel Time
0..........0..................Sun Oct 04 05:11:51 GST 2015........Origin1.........Destination1..............Sun Oct 04 05:11:51 GST 2015
1..........1..................Sun Oct 04 05:11:51 GST 2015........Origin2.........Destination2..............Sun Oct 04 05:11:51 GST 2015
2..........2..................Sun Oct 04 05:11:51 GST 2015........Origin3.........Destination3..............Sun Oct 04 05:11:51 GST 2015
3..........3..................Sun Oct 04 05:11:51 GST 2015........Origin4.........Destination4..............Sun Oct 04 05:11:51 GST 2015
10..........4..................Sun Oct 04 05:11:51 GST 2015........Origin11.........Destination11..............Sun Oct 04 05:11:51 GST 2015
11..........5..................Sun Oct 04 05:11:51 GST 2015........Origin12.........Destination12..............Sun Oct 04 05:11:51 GST 2015
12..........6..................Sun Oct 04 05:11:51 GST 2015........Origin13.........Destination13..............Sun Oct 04 05:11:51 GST 2015
13..........7..................Sun Oct 04 05:11:51 GST 2015........Origin14.........Destination14..............Sun Oct 04 05:11:51 GST 2015
14..........8..................Sun Oct 04 05:11:51 GST 2015........Origin15.........Destination15..............Sun Oct 04 05:11:51 GST 2015
5..........9..................Sun Oct 04 05:11:51 GST 2015........Origin6.........Destination6..............Sun Oct 04 05:11:51 GST 2015
6..........10..................Sun Oct 04 05:11:51 GST 2015........Origin7.........Destination7..............Sun Oct 04 05:11:51 GST 2015
7..........11..................Sun Oct 04 05:11:51 GST 2015........Origin8.........Destination8..............Sun Oct 04 05:11:51 GST 2015
8..........12..................Sun Oct 04 05:11:51 GST 2015........Origin9.........Destination9..............Sun Oct 04 05:11:51 GST 2015
id_______Leg______________Departure Time___________________________Origin_________Destination_____________Travel Time
0..........0..................Sun Oct 04 05:11:51 GST 2015........Origin1.........Destination1..............Sun Oct 04 05:11:51 GST 2015
1..........1..................Sun Oct 04 05:11:51 GST 2015........Origin2.........Destination2..............Sun Oct 04 05:11:51 GST 2015
2..........2..................Sun Oct 04 05:11:51 GST 2015........Origin3.........Destination3..............Sun Oct 04 05:11:51 GST 2015
3..........3..................Sun Oct 04 05:11:51 GST 2015........Origin4.........Destination4..............Sun Oct 04 05:11:51 GST 2015
5..........4..................Sun Oct 04 05:11:51 GST 2015........Origin6.........Destination6..............Sun Oct 04 05:11:51 GST 2015
6..........5..................Sun Oct 04 05:11:51 GST 2015........Origin7.........Destination7..............Sun Oct 04 05:11:51 GST 2015
7..........6..................Sun Oct 04 05:11:51 GST 2015........Origin8.........Destination8..............Sun Oct 04 05:11:51 GST 2015
8..........7..................Sun Oct 04 05:11:51 GST 2015........Origin9.........Destination9..............Sun Oct 04 05:11:51 GST 2015
10..........8..................Sun Oct 04 05:11:51 GST 2015........Origin11.........Destination11..............Sun Oct 04 05:11:51 GST 2015
11..........9..................Sun Oct 04 05:11:51 GST 2015........Origin12.........Destination12..............Sun Oct 04 05:11:51 GST 2015
12..........10..................Sun Oct 04 05:11:51 GST 2015........Origin13.........Destination13..............Sun Oct 04 05:11:51 GST 2015
13..........11..................Sun Oct 04 05:11:51 GST 2015........Origin14.........Destination14..............Sun Oct 04 05:11:51 GST 2015
14..........12..................Sun Oct 04 05:11:51 GST 2015........Origin15.........Destination15..............Sun Oct 04 05:11:51 GST 2015

How to know if a thread was waked up or time sliced (Producer-Consumer)

I'm learning multi-thread in java and I've faced with a behavior that I can't understand why.
Before, some explanations: the producer needs to produce until the list is full. When producing, nothing stops consumer from consuming. Consumer consumes until the list is empty. The producer only starts to produce when the list has <10 elements.
Here is my code:
Producer class
class Producer extends Thread {
private MyList list;
public Producer(MyList list) {
this.list = list;
}
public void run() {
for (int i = 0; i < 1000; i++) {
try {
list.put();
} catch (InterruptedException e) {
System.out.println("I WAS INTERRUPTED");
}
}
}
}
Consumer
class Consumer extends Thread {
private MyList list;
public Consumer(MyList list) {
this.list = list;
}
public void run() {
for (int i = 0; i < 1000; i++) {
try {
list.get();
} catch (InterruptedException e) {
System.out.println("I WAS INTERRUPTED 2");
}
}
}
}
List that has the shared resources
public class MyList {
private String[] dates = new String[100];
private int index = -1;
public int getIndex() {
return index;
}
public synchronized void put() throws InterruptedException {
if ((getIndex() + 1) == 100) {
System.out.println("List is full");
wait();
}
/**
* Here I need to know if this thread was woke up by the consumer, or it was 'restaured' due time-slice
*
*/
if (Thread.currentThread().isInterrupted() && getIndex() >= 10) {
System.out.println("List doesn't have the minimun quantity to start a production");
wait();
}
dates[++index] = new Date().toString();
System.out.println("put " + dates[index] + " at " + index);
notifyAll();
}
public synchronized void get() throws InterruptedException {
if (getIndex() < 0)
wait();
System.out.println("got " + dates[index--] + " at " + (index + 1));
/**
* Basically, to this example work I would need to put, if (getIndex() < 10) notifyAll() here,
* but that is a behavior for the producer and should not be in the consumer
*
*/
notifyAll();
}
}
Then
public class Main {
public static void main(String[] args) {
MyList list = new MyList();
Thread producer = new Producer(list);
Thread consumer = new Consumer(list);
producer.start();
consumer.start();
}
}
Sorry for that bunch of code, but it's not complicated code :)
Ok, go to the doubt, why those I WAS INTERRUPTED are never called?
and why (probably related with above) that List doesn't have the minimun quantity to start a production is also never called?
An actual output:
....
....
put Thu Oct 01 02:15:12 BRT 2015 at 93
put Thu Oct 01 02:15:12 BRT 2015 at 94
put Thu Oct 01 02:15:12 BRT 2015 at 95
put Thu Oct 01 02:15:12 BRT 2015 at 96
put Thu Oct 01 02:15:12 BRT 2015 at 97
put Thu Oct 01 02:15:12 BRT 2015 at 98
put Thu Oct 01 02:15:12 BRT 2015 at 99
List is full
got Thu Oct 01 02:15:12 BRT 2015 at 99
put Thu Oct 01 02:15:12 BRT 2015 at 99 <- this wouldn't happen
List is full
got Thu Oct 01 02:15:12 BRT 2015 at 99
put Thu Oct 01 02:15:12 BRT 2015 at 99 <- this wouldn't happen
List is full
...
...
EDIT
I've confused the things, I never call interrupt on my code, but this is not my purpose.
I want to know when the thread was 'woke up' by another thread and not from jvm due to the time-slice
You are not calling interrupt() method to interrupt the thread. Try the following code in main method:
producer.start();
consumer.start();
producer.interrupt();
consumer.interrupt();
Here is one sample output:
put Thu Oct 01 10:56:10 IST 2015 at 10
List doesn't have the minimun quantity to start a production
I WAS INTERRUPTED
got Thu Oct 01 10:56:10 IST 2015 at 10
got Thu Oct 01 10:56:10 IST 2015 at 9
got Thu Oct 01 10:56:10 IST 2015 at 8
got Thu Oct 01 10:56:10 IST 2015 at 7
got Thu Oct 01 10:56:10 IST 2015 at 6
got Thu Oct 01 10:56:10 IST 2015 at 5
got Thu Oct 01 10:56:10 IST 2015 at 4
got Thu Oct 01 10:56:10 IST 2015 at 3
got Thu Oct 01 10:56:10 IST 2015 at 2
got Thu Oct 01 10:56:10 IST 2015 at 1
got Thu Oct 01 10:56:10 IST 2015 at 0
I WAS INTERRUPTED 2
put Thu Oct 01 10:56:10 IST 2015 at 0
The points to note (taken from official tutorial) :
A thread sends an interrupt by invoking interrupt on the Thread object for the thread to be interrupted. For the interrupt mechanism to work correctly, the interrupted thread must support its own interruption.
The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.

how to find the day in the month in java?

this is what i do to get date in java :
Date date = (new GregorianCalendar(year,month - 1, i)).getTime(); // year,month,day
SimpleDateFormat f = new SimpleDateFormat("EEEE");
nameofday = f.format(date);
when i print the date Object it gives me the answer like follows :
Sun Apr 01 00:00:00 IST 2012
Mon Apr 02 00:00:00 IST 2012
Tue Apr 03 00:00:00 IST 2012
Wed Apr 04 00:00:00 IST 2012
Thu Apr 05 00:00:00 IST 2012
Fri Apr 06 00:00:00 IST 2012
Sat Apr 07 00:00:00 IST 2012
from this i want to get only the day ex: 01,02,03,04,05,etc.
How to do this in java?
Regards
Tony
If you want the day as a number, use:
int dayOfMonth = gregorianCalendarInstance.get(Calendar.DATE);
If you want a string like "05", change your date format to dd, that is:
SimpleDateFormat f = new SimpleDateFormat("dd");
Your output is not the nameofday. If you printed nameofday, it would print "saturday" or "friday". If you want the day in the month on two characters, as indicated in the javadoc of SimpleDateFormat, you must use "dd" for the pattern:
Date date = ...
DateFormat df = new SimpleDateFormat("dd");
System.out.println(df.format(date));
You should really learn to read documentation.

Categories