我想同步我的应用程序,因为有时服务器会向错误的用户发送消息.我使用synchronized块来同步队列但我的解决方案不起作用 - 有时用户收到的消息不适合他.
这是代码(server.java):( InWorker - 接收来自用户的消息,OutWorker- 向用户发送消息)每个用户都有自己的类(线程) - MiniServer(包含两个线程:InWorker和OutWorker).
class InWorker implements Runnable{
String slowo=null;
ObjectOutputStream oos;
ObjectInputStream ois;
ConcurrentMap<String,LinkedBlockingQueue<Message>> map=new ConcurrentHashMap<String, LinkedBlockingQueue<Message>>();
Message message=null;
InWorker(ObjectInputStream ois,ConcurrentMap<String,LinkedBlockingQueue<Message>> map) {
this.ois=ois;
this.map=map;
}
public void run() {
while(true) {
//synchronized(queue) {
try {
message = (Message) ois.readObject();
slowo=message.msg;
if(slowo!=null && !slowo.equals("Bye")) {
if(!map.containsKey(message.id)) {
map.putIfAbsent(message.id, new LinkedBlockingQueue<Message>());
try {
map.get(message.id).put(message);
} catch (InterruptedException ex) {
Logger.getLogger(Communicator.class.getName()).log(Level.SEVERE, null, ex);
}
}
else
{
try …Run Code Online (Sandbox Code Playgroud) MSDN告诉我,使用锁相当于使用监视器,但更简洁,更不容易出错.
你能给我一个简单的(单个过程)例子为什么我会被迫使用,Monitor因为它无法完成lock?
以下程序的行为是什么,静态同步方法和实例同步方法试图在不同的线程中访问同一类的静态字段?任何线程都会被阻止吗?它非常令人困惑.
class MyClass
{
public static int i = 5;
public synchronized void m1()
{
System.out.println(i); //uses static field i of MyClass
//T1 is executing this method
}
public static synchronized void m3()
{
//T2 will be able to call this method on same object lock while it is using
//static field i???
System.out.println(i);//uses static field i of MyClass
}
}
Run Code Online (Sandbox Code Playgroud) 几天前,我正在比较我的一些代码的性能,我执行一个非常简单的替换和Thrust实现相同的算法.我发现一个数量级(!)的不匹配有利于Thrust,所以我开始让我的调试器"冲浪"到他们的代码中以发现魔法发生的地方.
令人惊讶的是,我发现我的非常直接的实现实际上非常类似于他们的,一旦我摆脱了所有的functor东西并得到了细节.我看到Thrust有一个聪明的方法来决定块_size和grid_size(顺便说一句:确切地说,它是如何工作的?!),所以我只是采取了他们的设置并再次执行我的代码,因为它们非常相似.我增加了几微秒,但情况几乎相同.然后,最后,我不知道为什么,只是"尝试"我删除了我的内核和BINGO之后的cudaThreadSynchronize()!我将差距归零(并且更好),并获得了整个执行时间的数量级.访问我的数组值我发现它们完全符合我的预期,所以正确执行.
现在的问题是:我什么时候可以摆脱cudaThreadSynchronize(et similia)?为什么会造成如此巨大的开销?我看到Thrust本身在最后没有同步(synchronize_if_enabled(const char*message)是一个NOP,如果没有定义宏__THRUST_SYNCHRONOUS而且它不是).细节和代码如下.
// my replace code
template <typename T>
__global__ void replaceSimple(T* dev, const int n, const T oldval, const T newval)
{
const int gridSize = blockDim.x * gridDim.x;
int index = blockIdx.x * blockDim.x + threadIdx.x;
while(index < n)
{
if(dev[index] == oldval)
dev[index] = newval;
index += gridSize;
}
}
// replace invocation - not in main because of cpp - cu separation
template <typename T>
void callReplaceSimple(T* dev, const int n, const T …Run Code Online (Sandbox Code Playgroud) 我有以下测试项目:
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class myThreadTest {
private static final Logger log = LoggerFactory.getLogger(myThreadTest.class);
private ScheduledExecutorService executorService1 = Executors.newSingleThreadScheduledExecutor();
private ScheduledExecutorService executorService2 = Executors.newSingleThreadScheduledExecutor();
private Future<?> task1;
private Future<?> task2;
private class Task1 implements Runnable {
@Override
public synchronized void run() {
log.debug("-----------------------");
for (int i = 0; i < 100; i++) {
log.debug("{} Hello from Task 1",i);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.debug("-----------------------"); …Run Code Online (Sandbox Code Playgroud) 我想就此解决一个小纠纷.任何帮助将不胜感激.
我编写了自己的文件处理程序,它附加到记录器.这是一个文件处理程序,并由多个线程访问,我使用同步,以确保在写入过程中没有冲突.此外,它是一个滚动日志,所以我也关闭并打开文件,也不希望有任何问题.
他对此的回应是(从电子邮件中粘贴)
我坚信Handler中的同步非常糟糕.这么简单的任务太复杂了.所以,我想说为什么不为每个线程使用一个实例?
从性能和内存管理的角度来看,你会说什么更好.非常感谢您的回复.每当在多线程应用程序中涉及写入和读取时,我一直在Java应用程序上使用同步,并且没有听说过任何严重的性能问题.
所以,我想知道是否有任何问题,我真的应该切换到每个线程一个实例.
一般来说,使用同步的垮台是什么?
编辑:我之所以编写自定义文件处理程序(是的,我喜欢slf4j),是因为我的自定义处理程序一次处理两个文件,另外我还有很少的其他函数在写入文件时执行.
我需要像这样的线程安全的arraylist.
public class BookingList {
private List<Booking> bookings;
public BookingList() {
bookings = Collections.synchronizedList(new ArrayList<Booking>());
}
@Override
public void addBooking(Booking booking)
{
synchronized (bookings) {
bookings.add(booking);
}
}
@Override
public void removeBooking(Booking booking)
{
synchronized (bookings) {
bookings.remove(booking);
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据java doc,当使用Collections.synchronizedList时,需要同步对列表的每次访问.我不确定我的同步块是否会这样做?
我使用的synchronized块是否相当于
...
public synchronized void addBooking(Booking booking) {
bookings.add(booking);
}
Run Code Online (Sandbox Code Playgroud)我应该像这样使用ReentrantLock吗?
private Lock lock = new ReentrantLock();
public void addBooking(Booking booking) {
try {
lock.lock;
bookings.add(booking);
} finally {
lock.release();
}
}
Run Code Online (Sandbox Code Playgroud)我试图创建一个五个线程,因此如果一个线程在一个对象上调用synchronized方法(在这种情况下是objsyn),那么所有其他线程应该等到线程完成对象.因此输出应该按顺序从线程1到线程5.但输出结果不合时宜.
class synctest extends Thread
{
public synchronized void display()
{
try{Thread.sleep(5000*((long)(Math.random())));}
catch(Exception e){}
System.out.println("From synchornized thread "+ Thread.currentThread().getName());
}
public synchronized void run()
{
synctest objsyn = new synctest();
objsyn.display();
}
public static void main(String args[])
{
synctest objsy = new synctest();
Thread t1 = new Thread(objsy,"Thread 1");
Thread t2 = new Thread(objsy,"Thread 2");
Thread t3 = new Thread(objsy,"Thread 3");
Thread t4 = new Thread(objsy,"Thread 4");
Thread t5 = new Thread(objsy,"Thread 5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
Run Code Online (Sandbox Code Playgroud) 我有以下课程表现如此糟糕.它由3个线程类组成,序列不正确,也是输出.任何人都知道如何纠正?
输出 -
ANOTHER MY_INT to 1
Got Change for MY_INT : 1
Incrementing MY_INT to 1
Incrementing MY_INT to 2
Got Change for MY_INT : 2
ANOTHER MY_INT to 2
Incrementing MY_INT to 3
ANOTHER MY_INT to 3
Got Change for MY_INT : 3
Incrementing MY_INT to 4
Got Change for MY_INT : 4
ANOTHER MY_INT to 4
Incrementing MY_INT to 5
ANOTHER MY_INT to 5
Got Change for MY_INT : 5
MY_INT:: 5
Run Code Online (Sandbox Code Playgroud)
码:
public class VolatilityTest { …Run Code Online (Sandbox Code Playgroud) 我创建了一个程序,它创建了1000个线程,每个线程将1加入到变量sum中.我的问题是我得到的输出只有1秒.
这是程序:
class Threading implements Runnable{
T6_Q1 sumObject=new T6_Q1();
Thread t;
Threading(){
t=new Thread(this);
t.start();
}
@Override
public void run() {
setSumValue();
System.out.println(sumObject.getSum());
}
public void setSumValue(){
Integer value=sumObject.getSum().intValue()+1;
sumObject.setSum(value);
}
}
public class T6_Q1
{
Integer sum =new Integer(0);
public void setSum(int value){
this.sum=new Integer(value);
}
//method to get the sum value
public Integer getSum(){
return this.sum;
}
public static void main(String[] args) {
//launches 1000 threads
for(int i=1;i<=1000;i++)
{
new Threading();
}
}
}
Run Code Online (Sandbox Code Playgroud)
即使我同步setSumValue方法我只得到1s.我在这做错了什么?(我很新线程所以仍然有点难以理解错误)
感谢您的时间.