I have a list of free sockets conn, and i put then in a Map , if status of free or inUse, but the synchronized dosent seens to be working correctly
this is my code:
my map is like this:
private ConcurrentHashMap<MVConnection, Boolean> listaConn = new ConcurrentHashMap<>();
my connManager is this:
public synchronized MVConnection getInstance() {
System.out.println("pass here on getInstance");
System.out.println("--------------------------------------------------------");
System.out.println("Before request Instance");
LogLinhas();
System.out.println("--------------------------------------------------------");
MVConnection searchResult = null;
System.out.println(Thread.currentThread().getName() + " is running");
while (searchResult == null) {
searchResult = this.listaConn.search(1, (conn, free) -> {
if (free) {
return conn;
}
return null;
});
}
notify();
System.out.println(Thread.currentThread().getName() + " notifying");
if (searchResult != null) {
this.listaConn.replace(searchResult, false);
try {
System.out.println("Set " + searchResult.getServerPort() + " as busy");
} catch (MVException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("--------------------------------------------------------");
System.out.println("After request Instance");
LogLinhas();
System.out.println("--------------------------------------------------------");
return searchResult;
}
and the function the request the cont is this:
public abstract class AbstractD3Dao<T extends Serializable> {
#Autowired
ConexaoD3 conexao;
protected MVConnection getCurrentSession() {
System.out.println("Abstract request the conn");
MVConnection connPool = null;
synchronized (conexao.getInstance()) {
while (connPool == null) {
try {
System.out.println("Aguardando Conexao");
System.out.println(Thread.currentThread().getName() + " is waiting");
wait();
} catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
connPool = conexao.getInstance();
}
}
try {
System.out.println(" Abstract assineg the PIB " + connPool.getServerPort() + "to use");
} catch (MVException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return connPool;
}
`
Related
I am trying to learn inter thread communication where I am using BlockingQueue.
I have written a producer which generate TaskId and insert it into BlockingQueue.
Now I have 2 consumers threads (name "1" and "0"). If taskId is odd, it is consumed by Thread "1" else "2".
#Override
public void run() {
while (true) {
while (queue.peek() != null && !name.equals(String.valueOf(queue.peek().intValue() % 2 ))) {
try {
System.out.println(name + ",consumed," + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
How can i make that check also here?
One way I am thinking, there could be other better ways also:
#Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
while (queue.peek() == null) {
//some sleep time
}
synchronized (lock) {
while (queue.peek() != null && !name.equals(String.valueOf(queue.peek().intValue() % 2 ))) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(queue.peek() != null) {
try {
System.out.println(name + ",consumed," + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notify();
}
}
}
Another Way: To have anotherLock that will be notified by producer thread whenever element is added to queue.
#Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
synchronized (anotherLock) {
while (queue.peek() == null) {
anotherLock.wait();
}
}
synchronized (lock) {
while (queue.peek() != null && !name.equals(String.valueOf(queue.peek().intValue() % 2 ))) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(queue.peek() != null) {
try {
System.out.println(name + ",consumed," + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notify();
}
}
}
first of all, I'm rather new to socket programming to go easy on me ;).
I have a Java program that uses client-server programming to communicate between 1 or more clients and the server. So the clients can send any number of messages to the server where the messages are dealt with and all is fine so far. Now I want to notify the clients of e.g. database changes on the server side. So for example if one client changes for example table A, the other clients should also be notified about this change.
What I have so far is the following (server):
ExecutorService executor = null;
try (ServerSocket socket = new ServerSocket(port);)
{
executor = Executors.newFixedThreadPool(getThreadCount(5));
while(true)
{
Socket clientSocket = socket.accept();
Runnable worker = new PCRequestMapper(clientSocket);
executor.execute(worker);
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
finally
{
if(executor != null)
{
executor.shutdown();
}
}
The request mapper class then looks like this:
public class PCRequestMapper implements Runnable
{
private Socket client = null;
private static Map<Integer, PCRequestData> requestData = null;
public PCRequestMapper(Socket client)
{
this.client = client;
}
#Override
public void run()
{
try (ObjectInputStream in = new ObjectInputStream(
client.getInputStream());
ObjectOutputStream writer = new ObjectOutputStream(
client.getOutputStream());)
{
System.out.println("Thread started in PCRequestHandler with name: "
+ Thread.currentThread().getName());
Object recObj = in.readObject();
// ToDo Do something
PCBaseRequest req = (PCBaseRequest) recObj;
System.out.println("Req type: " + req.getRequestType() + " name: "
+ req.getName());
PCRequestData data = requestData.get(req.getRequestType());
if(data == null)
{
PCException ex = new PCException();
ex.setStackTrace(new Throwable().getStackTrace());
PCBaseReply reply = getErrorReply("No mapped request handler found in services.xml for request: "+req.getRequestType()+" - "+req.getName(),
PCException.NO_MAPPED_HANDLER, ex);
writer.writeObject(reply);
}
else
{
Class<?> c = Class.forName(data.getMappedClass());
Constructor<?> cons = c.getConstructor();
PCIRequestHandler object = (PCIRequestHandler)cons.newInstance();
PCBaseReply reply = object.heyHo(req);
System.out.println("Writing reply: "+reply.getClass());
writer.writeObject(reply);
}
} catch (IOException ioe)
{
ioe.printStackTrace();
} catch (ClassNotFoundException cnfe)
{
cnfe.printStackTrace();
} catch (NoSuchMethodException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It basically takes a message (request), maps it to a configured class and then that class performs whatever action needed.
On the client side, I have a class called RequestSender, which is used to send arbitrary requests to the server:
public class PCRequestSender
{
private static int getPort(int defaultPort)
{
final String port = PCConfigHandler.getStringProperty("serverPort");
if (null != port)
{
try
{
return Integer.parseInt(port);
} catch (NumberFormatException e)
{
System.out.println("Value of port property"
+ " is not a valid positive integer [" + port + "]."
+ " Reverting to default [" + defaultPort + "].");
}
}
return defaultPort;
}
public static PCBaseReply sendRequest(PCBaseRequest req)
{
PCBaseReply reply = null;
int port = getPort(8081);
String address = PCConfigHandler.getStringProperty("serverAddress");
try (Socket serverSocket = new Socket(address, port);
ObjectOutputStream out = new ObjectOutputStream(
serverSocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(
serverSocket.getInputStream());)
{
out.writeObject(req);
Object recObj = in.readObject();
reply = (PCBaseReply) recObj;
System.out.println("Reply: "+reply);
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return reply;
}
}
Now I'm a bit at a loss, because I would also like to constantly listen to a server socket to catch notifications. Do I need another socket on the server side? Is my setup not tooooo ideal?
I'm helpful for any hints...thanks!
I want to write something to the end of the file every time the file is modified and I'm using this code :
public class Main {
public static final String DIRECTORY_TO_WATCH = "D:\\test";
public static void main(String[] args) {
Path toWatch = Paths.get(DIRECTORY_TO_WATCH);
if (toWatch == null) {
throw new UnsupportedOperationException();
}
try {
WatchService myWatcher = toWatch.getFileSystem().newWatchService();
FileWatcher fileWatcher = new FileWatcher(myWatcher);
Thread t = new Thread(fileWatcher, "FileWatcher");
t.start();
toWatch.register(myWatcher, StandardWatchEventKinds.ENTRY_MODIFY);
t.join();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and the thread class :
public class FileWatcher implements Runnable{
private WatchService myWatcher;
private Path toWatch;
String content = "Dong\n";
int counter = 0;
public FileWatcher (WatchService myWatcher, Path toWatch) {
this.myWatcher = myWatcher;
this.toWatch = toWatch;
}
#Override
public void run() {
try {
WatchKey key = myWatcher.take();
while (key != null) {
for (WatchEvent event : key.pollEvents()) {
//System.out.printf("Received %s event for file: %s\n", event.kind(), event.context());
//System.out.println(counter);
myWatcher = null;
File file = new File(Main.DIRECTORY_TO_WATCH + "\\" + event.context());
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
fw.write(counter + content);
fw.close();
counter++;
myWatcher = toWatch.getFileSystem().newWatchService();
toWatch.register(myWatcher, StandardWatchEventKinds.ENTRY_MODIFY);
// BufferedWriter bwWriter = new BufferedWriter(fw);
// bwWriter.write(content);
// bwWriter.close();
}
key.reset();
key = myWatcher.take();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I want to get in the file something like :
acasc 0dong
dwqcacesv 1dong
terert 2dong
However, now I'm getting this, because it writes too many times in the file:
acasc 0dong
1dong
...
50123dong
If I use System.out.println(counter); it works as I want to (prints the number of file changes correctly), but it goes wild on fw.write(counter + content);
Your thread's write is causing further changes to the file.
Self feeding loop.
public class AtrExceptionResolver implements HandlerExceptionResolver {
private final static Log log =LogFactory.getLog(AtrExceptionResolver.class);
#Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
boolean ajaxrequest = false;
if (request.getRequestURI().indexOf("/ajax/") > 0)
ajaxrequest = true;
if (ex instanceof AtrException) {
AtrException atrE = (AtrException) ex;
log.error(
"AtrException:code:" + atrE.getCode() + ",desc:"
+ atrE.getMsg(), ex);
if (ajaxrequest) {
PrintWriter out = null;
try {
out = response.getWriter();
out.print("{\"e\":\"" + atrE.getCode()
+ "\",\"message\":\"" + atrE.getMsg() + "\"}");
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
out.close();
}
} else {
try {
goToError(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
log.error("Exception:desc:" + ex.getMessage(), ex);
if (ajaxrequest) {
PrintWriter out = null;
try {
out = response.getWriter();
out.print("{\"e\":\"3\",\"message\":\"system error\"}");
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
out.close();
}
} else {
try {
goToError(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
private void goToError(HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.sendRedirect(request.getContextPath() + "/jsp/error.jsp");
}
atrException is defined by myself,so I do not want to printStackTrace() in console.only print it in log.
I debug it,found it print by standardwrappervalve.invoke().
How to not print atrException message in console?
If I understand your question then you want the exception stack trace in a String object which you can use it for logging.
You can use below method.
public String getErrorLog(Throwable throwable) {
if (throwable != null) {
StringWriter errors = new StringWriter();
throwable.printStackTrace(new PrintWriter(errors));
return errors.toString();
}
return "";
}
Returned value is stack trace which you can log.
return new ModelAndView();
This way can solve.
If I run the following program, the JVM will not terminate after execution. However, if I uncomment the line (// newFixedThreadPool.execute(new Producer3());) from the code, the program terminates after execution. I am aware because of the blocking nature of the queue the program does not terminate. In the context of the below code what part of the code blocks the termination of the JVM?
public class LinkedBlockingQueueExample {
public static void main(String[] args) {
final BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<String>(5);
final class Producer implements Runnable {
#Override
public void run() {
try {
blockingQueue.put("Joshua");
blockingQueue.put("Bloch");
System.out.println("Put Joshua in the queue");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
final class Producer1 implements Runnable {
#Override
public void run() {
try {
blockingQueue.put("Martin");
blockingQueue.put("Fowler");
System.out.println("Put Mr Fowler in the Queue");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
final class Producer3 implements Runnable {
#Override
public void run() {
try {
blockingQueue.put("Malcom");
blockingQueue.put("Gladwell");
System.out.println("Put an Outlier in the Queue");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
final class Consumer implements Runnable {
#Override
public void run() {
try {
System.out.println(getClass() + " " + blockingQueue.take());
System.out.println(getClass() + " " + blockingQueue.take());
System.out.println(getClass() + " " + blockingQueue.take());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
final class Consumer1 implements Runnable {
#Override
public void run() {
try {
System.out.println(getClass() + " " + blockingQueue.take());
System.out.println(getClass() + " " + blockingQueue.take());
System.out.println(getClass() + " " + blockingQueue.take());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
newFixedThreadPool.execute(new Producer());
newFixedThreadPool.execute(new Producer1());
// newFixedThreadPool.execute(new Producer3());
newFixedThreadPool.execute(new Consumer());
newFixedThreadPool.execute(new Consumer1());
newFixedThreadPool.shutdown();
}
}
Take() call is always blocking till elements become available..
if you don't want to block then user poll()
poll()
Retrieves and removes the head of this queue, or returns null if this queue is empty.
reference : http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedBlockingQueue.html#poll()
The extra "take" is blocking the termination. It blocks on the extra "take"