我正在实现一个应该模拟数据库的代码。在此过程中,我将同时运行相同代码的多个实例/客户端,并且需要一种方法来区分每次运行,因为每次实例运行自身时,它都应该向 PlaceHolder.txt 文件添加一个新行,当用户(实例)提交代码时,它应该只将其事务移动到 DataBase.txt 文件。这是事务类:
public class Transaction{
private final String name;
private final int id;
public Transaction(){
this.id = getId()+1;
this.name= "T"+id;
}
public String getName(){
return this.name;
}
public int getId(){
return this.id;
}
public String toString(){
return "Name: "+ name+"nID: "+id+"n";
}
调用它的函数是这个:
private ArrayList<Transaction> transaction;
private static int id;
private static String name;
//Not Working
public synchronized String NewTransaction() {
Transaction transaction;
transaction= new Transaction ();
transaction=transaction;
System.out.print(transaction.toString() + "n");
return transaction.toString();
}
问题:但是编码不起作用。当我运行代码时,结果将始终为 id=1。我在代码中做错了什么?
一些建议实施解决方案:
class Junk {
private class Transaction {
private final String name;
private final int id;
public Transaction(int id){
this.id = id;
this.name= "T"+id;
}
public String getName(){
return this.name;
}
public int getId(){
return this.id;
}
public String toString(){
return "Name: "+ name+"nID: "+id+"n";
}
}
private ArrayList<Transaction> transactions;
private int curr_id = 0;
private String name;
public synchronized String NewTransaction() {
curr_id++;
Transaction transaction = new Transaction(curr_id);
return transaction.toString();
}
}
int 的默认值为 0。因此,当您构造一个新的事务对象时,您会 this.id = getId()+1;将始终为 1 (0+1)。
你可以创建一个叫做 IdCreator 的新类.java有一个方法公共静态同步 getNewId() 和一个静态 int idToHandOut,在那里你跟踪给出的最后一个 id,当有人要求一个新的 id 时,你把它递增 1。
还有许多其他方法可以做到这一点 - 您可以将时间戳作为 id。
基本上,你不能按照你编写它的方式分配 id,因为它总是 1。
您可以通过一些修改来修复它:
class Transaction{
private static int ID; // static var for unique identifier
private final String name;
public final int id;
public Transaction(){
ID++;
this.id = ID
this.name= "T" + ID;
}
public int getId(){
return this.id;
}
...
}
现在你会得到不同的id:
Transaction t1 = new Transaction();
Transaction t2 = new Transaction();
System.out.println(t1.id); // id 1
System.out.println(t2.id); // id 2
,最好使用原子类型,尽管它可能会在极重负载下引入瓶颈,但对于中到高负载来说,它应该没问题。
package transaction;
import java.util.concurrent.atomic.AtomicInteger;
public class Transaction {
// static field to generate new numbers sequentially in thread-safe way
private static final AtomicInteger idProvider = new AtomicInteger(0);
private final int id;
private final String name;
public Transaction()
{
this.id = Transaction.idProvider.incrementAndGet();
this.name = "T"+id;
}
public String getName(){
return this.name;
}
public int getId(){
return this.id;
}
public String toString(){
return "Name: "+ name+"nID: "+id;
}
}
测试示例
package transaction;
public class Main {
public static void main(String[] args)
{
System.out.println("Single threaded test");
for(int i = 0; i < 3; i++)
{
Transaction t1 = new Transaction();
Transaction t2 = new Transaction();
System.out.println("t1: "+t1.toString());
System.out.println("t2: "+t2.toString());
}
System.out.println("nMulti-threaded test");
for(int i = 0; i < 3; i++)
{
Thread w = new Thread()
{
public void run()
{
try{ // simulate unpredictable execution via random delay in instance creation
Thread.currentThread().sleep((int)(Math.random()*10));
}
catch(InterruptedException ignore){}
Transaction t = new Transaction();
System.out.println(t);
}
};
w.start();
}
try{ //Wait for all threads to finish
Thread.currentThread().sleep(1000);
}
catch(InterruptedException ignore){}
System.out.println("Done");
}
}
结果:
Single threaded test
t1: Name: T1
ID: 1
t2: Name: T2
ID: 2
t1: Name: T3
ID: 3
t2: Name: T4
ID: 4
t1: Name: T5
ID: 5
t2: Name: T6
ID: 6
Multi-threaded test
Name: T7
ID: 7
Name: T8
ID: 8
Name: T9
ID: 9
Done
附言不知道你为什么要做这样的事情
transaction=transaction;