forked from TheAlgorithms/Java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CircularBuffer.java
124 lines (105 loc) · 3.56 KB
/
CircularBuffer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class CircularBuffer {
private char[] _buffer;
public final int _buffer_size;
private int _write_index = 0;
private int _read_index = 0;
private AtomicInteger _readable_data = new AtomicInteger(0);
public CircularBuffer(int buffer_size) {
if(!IsPowerOfTwo(buffer_size)) {
throw new IllegalArgumentException();
}
this._buffer_size = buffer_size;
_buffer = new char[buffer_size];
}
private boolean IsPowerOfTwo(int i) {
return (i & (i - 1)) == 0;
}
private int getTrueIndex(int i) {
return i % _buffer_size;
}
public Character readOutChar() {
Character result = null;
//if we have data to read
if(_readable_data.get() > 0) {
result = new Character(_buffer[getTrueIndex(_read_index)]);
_readable_data.decrementAndGet();
_read_index++;
}
return result;
}
public boolean writeToCharBuffer(char c) {
boolean result = false;
//if we can write to the buffer
if(_readable_data.get() < _buffer_size) {
//write to buffer
_buffer[getTrueIndex(_write_index)] = c;
_readable_data.incrementAndGet();
_write_index++;
result = true;
}
return result;
}
private static class TestWriteWorker implements Runnable {
String _alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
Random _random = new Random();
CircularBuffer _buffer;
public TestWriteWorker(CircularBuffer cb) {
this._buffer = cb;
}
private char getRandomChar() {
return _alphabet.charAt(_random.nextInt(_alphabet.length()));
}
public void run() {
while(!Thread.interrupted()) {
if(!_buffer.writeToCharBuffer(getRandomChar())){
Thread.yield();
try{
Thread.sleep(10);
} catch (InterruptedException e) {
return;
}
}
}
}
}
private static class TestReadWorker implements Runnable {
CircularBuffer _buffer;
public TestReadWorker(CircularBuffer cb) {
this._buffer = cb;
}
public void run() {
System.out.println("Printing Buffer:");
while(!Thread.interrupted()) {
Character c = _buffer.readOutChar();
if(c != null) {
System.out.print(c.charValue());
} else {
Thread.yield();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println();
return;
}
}
}
}
}
public static void main(String[] args) throws InterruptedException {
int buffer_size = 1024;
//create circular buffer
CircularBuffer cb = new CircularBuffer(buffer_size);
//create threads that read and write the buffer.
Thread write_thread = new Thread(new TestWriteWorker(cb));
Thread read_thread = new Thread(new TestReadWorker(cb));
read_thread.start();
write_thread.start();
//wait some amount of time
Thread.sleep(10000);
//interrupt threads and exit
write_thread.interrupt();
read_thread.interrupt();
}
}