public class LockExample {
public static void main(String[] args) {
SharedResource sharedResource = new SharedResource();
Thread A = new Thread(()->{for(int i = 0; i < 10; i++)sharedResource.print5();},"A");
Thread B = new Thread(()->{for(int i = 0; i < 10; i++)sharedResource.print10();},"B");
Thread C = new Thread(()->{for(int i = 0; i < 10; i++)sharedResource.print15();},"C");
A.start();
B.start();
C.start();
try {
A.join();
B.join();
C.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("totall calls: "+sharedResource.getTotalCalls());
}
}
class SharedResource{
private int number = 1;
private int totalCalls = 0;
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
public void print5(){
lock.lock();
try {
System.out.println("print5 running");
while(number != 2)condition1.await();
for(int i =0; i<5; i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
totalCalls++;
number = 3;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10(){
lock.lock();
try {
System.out.println("print10 running");
while(number != 1)condition2.await();
for(int i =0; i<10; i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
totalCalls++;
number = 2;
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15(){
lock.lock();
try {
System.out.println("print15 running");
while(number != 3)condition3.await();
for(int i =0; i<15; i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
totalCalls++;
number = 1;
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public int getTotalCalls() {
return totalCalls;
}
}
Hello guys, consider the code above, I thought the lock must lock the critical section that been surrounded by lock and unlock, but why the output look like this?
print5 running
print10 running
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
print10 running
print15 running
A 0
A 1
Why it go back to println("print10 running") again at output line 13?
I think it signal the next thread which is print15() then print15() get the lock and lock everything. Hence print10 can not go in to lock section anymore. So why it print "print10 running" which is inside the lock section again?
I'm trying to create a code in java that continuously spits out what the x variable is every 10 milliseconds until the user inputs the String that breaks the loop. I was wondering how to code it.. I have the following right now. The code is currently running and just stopping where the Scanner is suppose to scan for the next line instead of continuously printing out what variable x is.
public static void show() {
while (true) {
if (showWatch.elapsedTime1() > 10) {
System.out.println(x);
showWatch.start();
x = x + 1;
wait(1000);
}
else if (showWatch.elapsedTime1() < 10) {
while (showWatch.elapsedTime1() < 10) {
response = scan.nextLine();
}
if (response.equalsIgnoreCase("STOP")) {
break;
}
else if (showWatch.elapsedTime1() > 10) {
System.out.println(x);
showWatch.start();
x = x + 1;
wait(1000);
}
}
}
}
How do you code a loop that will only continuously print the variable's content until the user types in a word to stop the program?
The scanner will not work if something is printed during typing. But if the interval is big enough it could work. I use the Semaphore so that the Printer-Thread sleeps as long he has no ticket.
public class Printer extends Thread {
public Semaphore stopped = new Semaphore(1);
private int x;
#Override
public void run() {
while (true) {
try {
stopped.acquire();
System.out.println(++x);
stopped.release();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Printer printer = new Printer();
printer.start();
Scanner scan = new Scanner(System.in);
while(true) {
String command = scan.nextLine();
if ("BREAK".equals(command)) {
printer.stopped.acquire(1);
} else if ("RESTART".equals(command)) {
printer.stopped.release(1);
}
}
}
It's my second time asking here and straight to the point. I can't seem to find a solution and I know it's not impossible. I wrote a java program that can generate a set of combination of any length, when I stop the program I don't want to start from the beginning how can I pick up from where I stopped?
Thanks.
Example (for length 3):
If I start from aaa ==> 9zI and I stop the program here, I don't want to start from aaa all over but start from 9zI and continue to 999. I just want to continue from where I left off.
public class Main {
public static void main(String[] args) {
S_Permutation sp = new S_Permutation();
String text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
FileClass.fileExist("new.txt", true);
System.out.println("");
sp.permutation(text, "", 7, "sha256.txt","Kaaaaaa");
}
}
=====================================================================
public class S_Permutation {
private List<String> permutation;
public S_Permutation() {
permutation = new ArrayList<>();
}
public boolean saveThis(String words, char a, int limit) {
int count = 0;
limit++;
for (char character : words.toCharArray()) {
if (count == limit) {
return false;
}
if (character == a) {
count++;
} else {
count = 0;
}
}
return count < limit;
}
private int counter = 0;
private boolean seen = false;
public void permutation(String str, String prefix, int lengthOfPermutationString, String filename, String startPoint) {
if (prefix.equalsIgnoreCase(startPoint))
{
seen = true;
}
if (counter == 0) {
if (startPoint.length() != lengthOfPermutationString) {
for (int i = startPoint.length(); i < lengthOfPermutationString; i++) {
startPoint += str.charAt(0);
}
}
counter = -45;
}
if (prefix.length() == lengthOfPermutationString) {
boolean savethis = true;
for (int i = 0; i < prefix.length(); i++) {
savethis = this.saveThis(prefix, prefix.charAt(i), 13);
if (!savethis) {
break;
}
}
if (savethis && seen) {
System.out.println(prefix);
//permutation.add(prefix);
}
} else {
for (int i = 0; i < str.length(); i++) {
if (permutation.size() == 1000) {
FileClass.WriteFile("new.txt", permutation);
permutation.clear();
}
permutation(str, prefix + str.charAt(i), lengthOfPermutationString, filename, startPoint);
}
FileClass.WriteFile("new.txt", permutation);
permutation.clear();
}
}
}
=========================================================================
public class FileClass {
public static boolean WriteFile(String filename, List<String> doc) {
try {
if (!filename.contains(".txt")) {
filename += ".txt";
}
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
String writer = "";
writer = doc.stream().map((string) -> string + "\n").reduce(writer, String::concat);
raf.seek(raf.length());
raf.writeBytes(writer);
raf.close();
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("Error");
new Scanner(System.in).nextLine();
return false;
}
return true;
}
static RandomAccessFile raf;
public static boolean fileExist(String filename, boolean delete){
File file = new File(filename);
if (file.exists() && delete)
{
return file.delete();
}
return file.exists();
}
public static void WriteFile(String filename, String text) {
try {
if (!filename.contains(".txt")) {
filename += ".txt";
}
raf = new RandomAccessFile(filename, "rw");
long length = raf.length();
raf.setLength(length + 1);
raf.seek(raf.length());
raf.writeBytes(text + "\n");
} catch (Exception e) {
}
}
private static void write(List<String> records, Writer writer) throws IOException {
for (String record : records) {
writer.write(record);
}
writer.flush();
writer.close();
}
public static void stringWriter(List<String> records, String filename) {
try {
File file = new File(filename);
FileWriter writer = new FileWriter(file, true);
write(records, writer);
} catch (Exception ex) {
System.out.println(ex.getMessage());
new Scanner(System.in).nextLine();
}
}
public static boolean CloseFile() {
try {
raf.close();
return true;
} catch (Exception e) {
return false;
}
}
}
In order to add a "Resume" mechanism, you need to make your program idempotent. One way to do it, is instead of saving the permutations - save to file the parameters that are sent to permutation on each iteration:
now each time that the program starts, it will check what were the last parameters that permutation was called with (the last line in the file), and start from there (when the program starts on the first time, nothing will be written in the file - so it will start from the beginning).
After that the recursion finished, we can call another method that will go over the lines of the file, and read only the permutations (ignoring the other parameters) and write them into a cleaner "final_result.txt" file.
Needless to say that this implementation is more costly (all the additional reads and write from disc) but that's the tradeoff for having it support "resume" operation.
To save/restore process in the middle of its work, you need something we can call a "state" and implement generating combinations in iterative way.
In my implementation the "state" is pos object (I assume set and k will not change on "resume").
My implementation of the problem would be following:
public class RepeatComb {
private int[] pos;
private String set;
public RepeatComb(String set, int k) {
this.set = set;
pos = new int[k];
}
public int[] getState() {return Arrays.copyOf(pos, pos.length);}
public void resume(int[] a) {pos = Arrays.copyOf(a,a.length);}
public boolean next() {
int i = pos.length-1;
for (int maxpos = set.length()-1; pos[i] >= maxpos; ) {
if (i==0) return false;
--i;
}
++pos[i];
while (++i < pos.length) pos[i]=0;
return true;
}
public String getCur() {
StringBuilder s = new StringBuilder(pos.length);
for (int i=0; i < pos.length; ++i)
s.append(set.charAt(pos[i]));
return s.toString();
}
public static void main(String[] args) {
int[] state;
String text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
RepeatComb comb = new RepeatComb(text, 3);
int stop = 10; //break after 10
do {
if (stop-- == 0) break;
System.out.println(comb.getCur());
} while (comb.next());
//save state
state = comb.getState();
System.out.println("---------");
//resume (with the same args: text,3)
stop = 10; //break after 10
comb = new RepeatComb(text, 3);
comb.resume(state); // resume here
do {
if (stop-- == 0) break;
System.out.println(comb.getCur());
} while (comb.next());
}
}
Update: I've added functions for getting state and resuming from it
and example of use. state array can be saved in file, then restored.
I'm learning JUC,I want to calculate the total time that the program runs with five threads,but it's blocked after print "1 2 3"。please tell me what the reason is ?
In addition, if I don't call the function "isPrime(int)",The program will execute normally.
public class TestCountDownLatch {
public static void main(String[] args) {
CountDownLatch cwt = new CountDownLatch(5);
Runnable runnable = new CountDownThread(cwt);
long start = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
new Thread(runnable).start();
}
try {
cwt.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("total time :" + (end - start));
}
}
class CountDownThread implements Runnable{
private CountDownLatch countdownLatch;
private int num = 1;
public CountDownThread(CountDownLatch countdownLatch) {
this.countdownLatch = countdownLatch;
}
#Override
public void run() {
try{
while(true){
synchronized (this) {
if(num > 100){
break;
}
if(isPrime(num)){
System.out.println(num++);
}
}
}
}finally{
countdownLatch.countDown();
}
}
private boolean isPrime(int i) {
for (int j = 2; j <= (i >> 1); j++) {
if(i % j == 0){
return false;
}
}
return true;
}
}
Your Runnable run method, is only incrementing num when its prime and hence when it encounters 4 which is not prime its not incrementing num and your program is in that state for rest of period when its running. Fiddled with below mentioned piece which makes it go beyond that point and break at 100.
#Override
public void run() {
try {
while (true) {
synchronized (this) {
num++; // initially assigning int num = 0, and then doing this
if (num > 100) {
break;
}
if (isPrime(num)) {
System.out.println(num);
}
}
}
} finally {
countdownLatch.countDown();
}
}
I have an array with the size of n which is filled with the numbers 1..n.
I need to sum this array using m threads by each time taking two elements, sum them up and inserting the sum back to the array.
Here is what I tried to do.
The synchronized part first
public class MultiThreadedSum {
private ArrayBuffer ArrayBufferInst;
private int Sum;
private boolean Flag, StopFlag;
public MultiThreadedSum(ArrayBuffer ArrayBufferInst) {
this.ArrayBufferInst = ArrayBufferInst;
Sum = 0;
Flag = false;
StopFlag = false;
}
public synchronized void Sum2Elements() {
while(Flag){
try {wait();}
catch (InterruptedException e){}
}
Flag = true;
if (StopFlag) {
notifyAll();
return;
}
System.out.println("Removing and adding 2 elements.");
Sum = ArrayBufferInst.Sum2Elements();
notifyAll();
}
public synchronized void InsertElement() {
while(!Flag){
try {wait();}
catch (InterruptedException e){}
}
Flag = false;
if (StopFlag) {
notifyAll();
return;
}
System.out.println("Inserting the sum.");
ArrayBufferInst.InsertElement(Sum);
if (ArrayBufferInst.RetunrSize() == 1) {
StopFlag = true;
}
System.out.println(ArrayBufferInst);
notifyAll();
}
public boolean ReturnStopFlag(){
return StopFlag;
}
#Override
public String toString(){
return ArrayBufferInst.toString();
}
}
I've splitted the m threads to 2 groups, half of them will do the summarization and half will do the adding using wait and notify.
public class Sum2ElementsThread implements Runnable{
private MultiThreadedSum MultiThreadedSumInst;
public Sum2ElementsThread( MultiThreadedSum MultiThreadedSumInst){
this.MultiThreadedSumInst = MultiThreadedSumInst;
}
#Override
public void run() {
while(!MultiThreadedSumInst.ReturnStopFlag())
MultiThreadedSumInst.Sum2Elements();
}
}
public class InsertThread implements Runnable{
private MultiThreadedSum MultiThreadedSumInst;
public InsertThread( MultiThreadedSum MultiThreadedSumInst) {
this.MultiThreadedSumInst = MultiThreadedSumInst;
}
#Override
public void run() {
while(!MultiThreadedSumInst.ReturnStopFlag()) {
MultiThreadedSumInst.InsertElement();
}
}
}
Here is part of the main:
ArrayBufferInst = new ArrayBuffer(n);
System.out.println("The Array");
System.out.println(ArrayBufferInst);
MultiThreadedSumInst = new MultiThreadedSum(ArrayBufferInst);
ExecutorService Threads = Executors.newCachedThreadPool();
for (i = 0; i < m/2; i++)
Threads.execute( new Sum2ElementsThread(MultiThreadedSumInst) );
for (; i < m; i++)
Threads.execute( new InsertThread(MultiThreadedSumInst) );
Threads.shutdown();
while(!MultiThreadedSumInst.ReturnStopFlag()){}
System.out.println("The sum of the array is " + MultiThreadedSumInst);
And the buffer
public class ArrayBuffer {
private ArrayList<Integer> ArrayBufferInst;
public ArrayBuffer(int SizeOfBuffer){
int i;
ArrayBufferInst = new ArrayList<>(SizeOfBuffer);
for (i = 0; i < SizeOfBuffer; i++){
ArrayBufferInst.add(i, i+1);
}
}
public int Sum2Elements(){
if (ArrayBufferInst.size() < 2){
return -1;
}
return ArrayBufferInst.remove(0) + ArrayBufferInst.remove(0);
}
public void InsertElement(int Elem) {
ArrayBufferInst.add(Elem);
}
public int RetunrSize(){
return ArrayBufferInst.size();
}
#Override
public String toString() {
return ArrayBufferInst.toString();
}
}
My question is about the end of the main, sometimes the program stop, sometime it doesn't, I know all the threads are exiting the run method because I checked that.
Sometimes I see the The sum of the array is message, sometimes I don't.
Your problem lies here:
public synchronized void Sum2Elements() {
while(Flag){
try {wait();}
catch (InterruptedException e){}
}
Flag = true;
// rest of method omitted here
}
When this part of the program is executed for the first time Flag is false and the loop is ignored. All subsequent executions of this method will result in a deadlock since this is the only place where you set Flag to false.
Not even interrupting will work, since you have no break in your loop and after the interruption you just go on to the next cycle and wait() forever.
Oh and read this - Java is not c#
It is really a very long code for you task.
Maybe i can propose a different sollution.
You can just split array for m parts (m - is a number of threads) - and each thread would sum it`s own part. When summing is over in each Thread - just sum all part results.
Or maybe i didnt get your task correctly. Specify more details please (the full task).