package xyz.zhouxy.plusone.commons.collection;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.annotation.concurrent.ThreadSafe;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
/**
* 将 {@link Table} 包装为同步集合,线程安全。
*
*
* 可通过以下方式构建一个线程安全的 {@link Table}
*
*
*
* SynchronizedTable.of(HashBasedTable.create())
*
*
*
* NOTE: 如果 {@link Table} 不需要更改,请使用 {@link ImmutableTable}
*
*
* @author ZhouXY
* @since 0.1.0-SNAPSHOT
* @see Table
* @see ImmutableTable
*/
@Beta
@ThreadSafe
public class SynchronizedTable implements Table, Serializable {
private static final long serialVersionUID = 3716653837549439569L;
@SuppressWarnings("serial")
private final Table table;
@SuppressWarnings("serial")
private final Object mutex;
private SynchronizedTable(Table table) {
this.table = Objects.requireNonNull(table);
this.mutex = this;
}
private SynchronizedTable(Table table, Object mutex) {
this.table = Objects.requireNonNull(table);
this.mutex = mutex;
}
public static SynchronizedTable of(Table table) {
if (table instanceof SynchronizedTable) {
return (SynchronizedTable) table;
} else {
return new SynchronizedTable<>(table);
}
}
public static SynchronizedTable of(Table table, Object mutex) {
if (table instanceof SynchronizedTable) {
SynchronizedTable srcTable = (SynchronizedTable) table;
return new SynchronizedTable<>(srcTable.table, mutex);
} else {
return new SynchronizedTable<>(table);
}
}
@Override
public boolean contains(Object rowKey, Object columnKey) {
synchronized (mutex) {
return this.table.contains(rowKey, columnKey);
}
}
@Override
public boolean containsRow(Object rowKey) {
synchronized (mutex) {
return this.table.containsRow(rowKey);
}
}
@Override
public boolean containsColumn(Object columnKey) {
synchronized (mutex) {
return this.table.containsColumn(columnKey);
}
}
@Override
public boolean containsValue(Object value) {
synchronized (mutex) {
return this.table.containsValue(value);
}
}
@Override
public V get(Object rowKey, Object columnKey) {
synchronized (mutex) {
return this.table.get(rowKey, columnKey);
}
}
@Override
public boolean isEmpty() {
synchronized (mutex) {
return this.table.isEmpty();
}
}
@Override
public int size() {
synchronized (mutex) {
return this.table.size();
}
}
@Override
public void clear() {
synchronized (mutex) {
this.table.clear();
}
}
@Override
public V put(R rowKey, C columnKey, V value) {
synchronized (mutex) {
return this.table.put(rowKey, columnKey, value);
}
}
@Override
public void putAll(Table extends R, ? extends C, ? extends V> table) {
synchronized (mutex) {
this.table.putAll(table);
}
}
@Override
public V remove(Object rowKey, Object columnKey) {
synchronized (mutex) {
return this.table.remove(rowKey, columnKey);
}
}
@Override
public Map row(R rowKey) {
synchronized (mutex) {
return this.table.row(rowKey);
}
}
@Override
public Map column(C columnKey) {
synchronized (mutex) {
return this.table.column(columnKey);
}
}
@Override
public Set> cellSet() {
synchronized (mutex) {
return this.table.cellSet();
}
}
@Override
public Set rowKeySet() {
synchronized (mutex) {
return this.table.rowKeySet();
}
}
@Override
public Set columnKeySet() {
synchronized (mutex) {
return this.table.columnKeySet();
}
}
@Override
public Collection values() {
synchronized (mutex) {
return this.table.values();
}
}
@Override
public Map> rowMap() {
synchronized (mutex) {
return this.table.rowMap();
}
}
@Override
public Map> columnMap() {
synchronized (mutex) {
return this.table.columnMap();
}
}
}
|