每个人都警告Java DateFormat不是线程安全的,理论上我理解这个概念.
但是我无法想象出由此产生的实际问题.比如,我在类中有一个DateFormat字段,并且在多线程环境中的类(格式化日期)中的不同方法中使用相同的字段.
这会导致:
另外,请解释原因.
我已经/看过一些spring-hibernate Web应用程序项目,它们具有与实际服务和dao类一样多的接口.
我一直认为这两个是这些单一实现接口的主要原因:
Spring可以将实际实现作为给定类中的依赖项连接(松散耦合)
public class Person {
@Autowired
private Address address;
@Autowired
private AccountDetail accountDetail;
public Person(Address address, AccountDetail accountDetail)
{ // constructor
Run Code Online (Sandbox Code Playgroud)在进行单元测试时,我可以创建模拟类并单独测试类.
Address mockedAddress = mock(Address);
AccountDetail mockedAccountDetail = mock(AccountDetail);
Person underTestPerson = new Person(mockedAddress, mockedAccountDetail);
// unit test follows
Run Code Online (Sandbox Code Playgroud)但是,最近,我意识到:
Spring可以将具体实现类连接为依赖项:
public class Person {
@Autowired
private AddressImpl address;
@Autowired
private AccountDetailImpl accountDetail;
public Person(AddressImpl address, AccountDetailImpl accountDetail) {
// constructor
Run Code Online (Sandbox Code Playgroud)
像EasyMock这样的模拟框架也可以模拟具体的类
AddressImpl mockedAddress = mock(AddressImpl);
AccountDetailImpl mockedAccountDetail = mock(AccountDetailImpl);
Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); …Run Code Online (Sandbox Code Playgroud) 考虑以下Spring Service类.定义的弹簧范围是Singleton.自动连接的两个服务bean作为下面类中的字段具有相似的结构 - 它们也由以下任一字段组成
等等.此模式总体上用于应用程序设计中.
@Service
public class DocumentService {
private final DocumentGenerationService documentGenerationService;
private final DocumentPublishService documentPublishService;
@Autowired
public DocumentService (DocumentGenerationService documentGenerationService,
DocumentPublishService documentPublishService) {
this.documentGenerationService = documentGenerationService;
this.documentPublishService = documentPublishService;
}
... methods follow
Run Code Online (Sandbox Code Playgroud)
说DocumentService类是不可变的是正确的,因为它不可能改变它的两个字段中的任何一个(可以通过容器本身只初始化一次的spring bean)?
在任何情况下,上面定义的DocumentService bean都可以被认为是线程安全的吗?如果遵循这个设计,整个应用程序也是线程安全的吗?
这是Rob Pike对此的幻灯片.每次我通过这个,我都觉得自己像个白痴.我无法弄清楚它的要点.众所周知,并发性是将复杂问题分解为更小的组件.如果你不能正确地将某些东西划分成较小的部分,那么使用并发很难解决它.
但是,一旦你实现了并发性,关于如何获得并行性的幻灯片中没有太多细节.在Lesson幻灯片(第52期)中,他说并发 - "甚至可能是并行".但问题是 - 何时以及如何才能正确有效地实现并发性并行化?
我的猜测是,在引擎盖下,Rob指出开发人员应该在并发级别工作 - 并行性应该是语言/ vm的关注(gomaxprocs?).只关心智能分解成更小的单元,只关心正确的并发性 - 并行性将由"系统"来处理.
请说清楚.
根据我的理解,JDBC连接池(在基本级别)以这种方式工作:
但是,每当我在JDBC连接池讨论中听到"连接重用"这个术语时,我就会感到困惑.何时进行连接重用?
这是否意味着连接池为两个不同的数据库交互提供相同的连接(不关闭它)?或者,有没有办法继续使用连接,即使它在数据库调用后关闭?
我的职业生涯主要是在中小型Java项目中工作.我最近在eclipse中看到了一个包含30个项目的庞大项目.我真的没有创建许多小项目的概念,然后维护项目间的依赖关系.我们什么时候更喜欢这个而不是简单地组织包装?
我猜这是一个maven的事情(主要是使用Ant).我一直在阅读Maven的模块概念 - 我在网上看到一些链接,建议在父模块下为web,dao和服务层创建不同的模块.这真的是一种常见/最佳做法吗?
有或没有maven - 这种分裂真的让生活更轻松吗?将所有内容都放在一个具有明确定义的不同层包结构的项目中是不是更紧凑?
我在下面的代码中关注的是构造函数的参数实际上并没有直接映射到类的实例字段.实例字段从参数中获取值,并且我正在使用initalize方法.此外,我做了一些事情,以便创建的对象可以直接在后面的代码中使用,例如调用drawBoundaries().我觉得它正在做一个抽象意义上创建(初始化)Canvas的意思.
我的构造函数做得太多了吗?如果我添加方法从外部显式调用构造函数中的东西,那就错了.请让我知道你的看法.
public class Canvas {
private int numberOfRows;
private int numberOfColumns;
private final List<Cell> listOfCells = new LinkedList<Cell>();
public Canvas(ParsedCells seedPatternCells) {
initalizeCanvas(seedPatternCells);
}
private void initalizeCanvas(ParsedCells seedPatternCells) {
setNumberOfRowsAndColumnsBasedOnSeedPatten(seedPatternCells);
drawBoundaries();
placeSeedPatternCellsOnCanvas(seedPatternCells);
}
...
Run Code Online (Sandbox Code Playgroud)
PS:对不起,如果这看起来像个愚蠢的问题; 我的代码将由OOP大师审核,我只是担心:-0
编辑:
我读到了一些关于initalizeCanvas()被覆盖的方法的担忧 - 幸运的是这些方法是私有的,不会调用任何其他方法.
无论如何,经过对网络的进一步研究后,我开始喜欢这个...我希望你们同意!! ??
public class Canvas {
private int numberOfRows;
private int numberOfColumns;
private final List<Cell> listOfCells = new LinkedList<Cell>();
private Canvas() {
}
public static Canvas newInstance(ParsedCells seedPatternCells) {
Canvas canvas = new Canvas();
canvas.setNumberOfRowsAndColumnsBasedOnSeedPatten(seedPatternCells);
canvas.drawBoundaries();
canvas.placeSeedPatternCellsOnCanvas(seedPatternCells);
return canvas; …Run Code Online (Sandbox Code Playgroud) 在Spring中使用@Autowired直接连接到具体类而不是接口(并使用'by type'自动装配)是否有意义?
如果一个类没有实现接口,那么通过构造函数或工厂实例化它会更好(保持简单); 而不是仅仅为了它而使它成为一个Spring bean.
如果此方法的变量'commonSet'是类级别字段,则以下代码是否会导致相同的问题.如果它是类级别字段,我将不得不在同步块中包装添加设置操作,因为HashSet不是线程安全的.我应该在下面的代码中做同样的事情,因为多个线程正在添加到集合,甚至当前线程可能会继续改变集合.
public void threadCreatorFunction(final String[] args) {
final Set<String> commonSet = new HashSet<String>();
final Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
commonSet.add(newValue());
}
}
};
new Thread(runnable, "T_A").start();
new Thread(runnable, "T_B").start();
}
Run Code Online (Sandbox Code Playgroud)
'commonSet'的引用是使用final锁定的.但是在其上运行的多个线程仍然可以破坏集合中的值(它可能包含重复项?).其次,混淆是因为'commonSet'是一个方法级变量 - 它的相同引用将在调用方法的堆栈内存(threadCreatorFunction)和运行方法的堆栈内存 - 这是正确的吗?
有很多与此相关的问题:
但是,我不能看到他们强调线程安全部分这种共享/传递可变性.
有没有人知道如何实现以下测试DAO的流程:
使用Spring,Hibernate,JUnit,Maven堆栈.
我知道最佳实践是我们为每个测试DAO(@BeforeClass)创建数据,并在完成所有测试后(@AfterClass)清理相同的数据.
但在我们的例子中,不同的数据库表之间存在太多的依赖关系(客户端的遗留数据库:(目前无法做任何事情).用测试数据填充每个表也需要许多其他表中的数据.所以,为每个DAO单独创建数据将非常困难且耗时.因此,我们确实只需要创建一次DB测试数据.
我使用BaseDAO中的静态块创建了测试数据(由每个DAO测试类扩展) - 显然只运行一次.但是当所有测试(所有DAO测试子类)完成时,如何清理相同的问题.在DAO Test类完成后,每次都会运行基类中的@AfterClass拆解方法.
请指教.
在Go中,如果我用指针定义一个函数作为接收器,它不应该只允许从指针调用函数吗?为什么可以从值本身调用此函数并具有相同的效果.
例如,在以下程序中:m1.reset()和m2.reset()具有相同的效果.即使m1是值,m2也是指针.
我有点困惑,因为有两种方法可以做同样的事情,我不确定应该遵循哪一种方法.虽然大多数代码遵循使用指针字段调用函数的约定.我错过了什么吗?
package main
import "fmt"
type MyStruct struct {
X int
}
func (m *MyStruct) reset() {
m.X = 0
}
func main() {
m1 := MyStruct{1}
m2 := &MyStruct{1}
fmt.Println(m1.X)
fmt.Println(m2.X)
m1.reset()
m2.reset()
fmt.Println(m1.X)
fmt.Println(m2.X)
}
Run Code Online (Sandbox Code Playgroud) 我正在研究这个,以了解新JMM中的最终字段的行为(5以后).这个概念很清楚:在正确构造对象之后,保证初始化的最终字段对所有线程的可见性.
但是在本节的最后,我读到了这个,这让我感到困惑:
现在,说完所有这些,如果在一个线程构造一个不可变对象(即一个只包含最终字段的对象)之后,你想确保所有其他线程都能正确看到它,你通常还需要使用同步.例如,没有其他方法可以确保第二个线程可以看到对不可变对象的引用.
这是否意味着虽然单个最终字段(组成不可变对象)没有同步(例如,此处可见性)问题.但是,首次在线程中创建的不可变对象本身在其他线程中可能不可见(正确创建)?
如果是这样,虽然我们可以跨线程共享初始化的不可变对象而没有任何线程不安全的担忧,但在创建时,他们需要"特别关注"线程安全,就像其他mutable一样?
在调用plain()方法之前,以下代码在synchronized sync()方法中阻塞.为什么会这样,本地锁块不应该只调用同步方法 - 例如,如果plain()同步,这种行为也没问题.
由于java使用的监视器概念仅适用于同步的方法/块 - 根据定义它不应该影响非同步代码的执行.这种情况总是如此,或者这种行为是否特定于JVM实现.
public class Main {
public static void main(final String[] args) {
final Main main = new Main();
new Thread(new Runnable() {
@Override
public void run() {
main.sync();
}
}).run();
main.plain();
}
public synchronized void sync() {
try {
System.out.println("sleeping...");
Thread.sleep(2000);
System.out.println("out...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void plain() {
System.out.println("plain...");
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
sleeping...
out...
plain...
Run Code Online (Sandbox Code Playgroud) java ×9
concurrency ×5
spring ×4
final ×2
maven-2 ×2
ant ×1
coding-style ×1
date-format ×1
dependencies ×1
eclipse ×1
go ×1
hibernate ×1
immutability ×1
jdbc ×1
junit4 ×1
mocking ×1
oop ×1
pointers ×1
singleton ×1
synchronized ×1
syntax ×1
testing ×1