使用Java指令重新排序时,JVM会在编译时或运行时更改代码的执行顺序,这可能导致无关的语句无序执行.
所以我的问题是:
有人可以提供示例Java程序/片段,它可靠地显示指令重新排序问题,这也不是由其他同步问题(例如缓存/可见性或非原子r/w)引起的,就像我在这样的演示中尝试失败一样在我之前的问题中)
为了强调,我不是在寻找理论重新排序问题的例子.我正在寻找的是通过查看正在运行的程序的错误或意外结果来实际演示它们的方法.
除了一个错误的行为示例,只显示在一个简单程序的程序集中发生的实际重新排序也可能是好的.
java multithreading compiler-optimization instruction-reordering
如何使用 C++20 概念限制可变参数模板和折叠表达式中允许的类型?
例如,假设我想限制以下折叠表达式仅支持整数类型,我该怎么做?
#include <string>
#include <iostream>
#include <concepts>
using namespace std;
template<typename... Args> // requires (is_integral<Args>::value )
int sum(Args... args) { return (... + args); }
int main()
{
cout << sum(1,2,3);
}
Run Code Online (Sandbox Code Playgroud) 我最近注意到,Spring成功拦截了@Configuration类中的内部类函数调用,但没有拦截常规的bean。
这样的电话
@Repository
public class CustomerDAO {
@Transactional(value=TxType.REQUIRED)
public void saveCustomer() {
// some DB stuff here...
saveCustomer2();
}
@Transactional(value=TxType.REQUIRES_NEW)
public void saveCustomer2() {
// more DB stuff here
}
}
Run Code Online (Sandbox Code Playgroud)
未能启动新事务,因为尽管在CustomerDAO代理中执行了saveCustomer()的代码,但在已解包的CustomerDAO类中执行了saveCustomer2()的代码,正如我在调试器中查看“ this”所看到的,等等Spring没有机会拦截对saveCustomer2的调用。
但是,在以下示例中,当transactionManager()调用createDataSource()时,它将被正确拦截并调用代理的createDataSource(),而不是未包装类的调用,而在调试器中查看“ this”可以证明这一点。
@Configuration
public class PersistenceJPAConfig {
@Bean
public DriverManagerDataSource createDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
//dataSource.set ... DB stuff here
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager( ){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(createDataSource());
return transactionManager;
}
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,为什么在第二个示例中Spring可以正确地拦截内部类函数调用,而在第一个示例中则不能。是否使用不同类型的动态代理?
编辑: 从这里的答案和其他来源,我现在了解以下内容:@Transactional是使用Spring AOP实现的,其中代理模式通过包装/组合用户类来执行。AOP代理足够通用,因此许多方面都可以链接在一起,并且可以是CGLib代理或Java动态代理。
在@Configuration类中,Spring还使用CGLib创建一个从用户@Configuration类继承的增强类,并在调用用户的/ super函数之前用做一些额外工作的函数覆盖用户的@Bean函数,例如检查是否是否是该函数的首次调用。该课程是代理吗?这取决于定义。您可能会说这是一个使用真实对象继承的代理,而不是使用组合包装。
总而言之,从这里给出的答案中,我了解到这是两种完全不同的机制。为什么做出这些设计选择是另一个悬而未决的问题。
为什么这个代码在右侧使用显式静态字段表示法编译,但不是没有?
public class A
{
static int a = ++A.a; // compiles
//static int a = ++a; // error - cannot reference a field before it is defined
public static void main(String[] args) {
System.out.println(a);
}
}
Run Code Online (Sandbox Code Playgroud) 方便的initializer_list语法似乎是以无法移动列表成员、创建不必要的副本为代价的。
struct A
{
// some members which are dynamic resources...
A() { cout << "Default Constructor\n"; }
A(const A& original) { cout << "Copy constructor\n"; }
A(A&& original) { cout << "Move constructor\n"; }
};
int main() {
vector<A> v1{ A() , A() }; // calls copy
vector<A> v2;
v2.push_back(A()); v2.push_back(A()); // calls move
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,这是因为取消引用初始化器迭代器会给出const T,即使尝试移动时也会复制它。
有解决方法吗?
阅读/sf/answers/3101541901/,提出了一种使用可变参数模板的解决方案,如下所示:
template<class Array> struct maker;
// a maker which makes a std::vector
template<class …Run Code Online (Sandbox Code Playgroud) 我想知道为什么我的程序输出I4 output\ I3 outputxef\xbc\x9f
var a = 4;\nvar i = 0;\nvar i3 = function() {\n console.log("I3 output")\n return i = i + 3\n}\nvar i4 = function() {\n console.log("I4 output")\n return i = 4\n}\n\n(a > 3) && i3() || (a < 5) && i4();\nconsole.log(i)Run Code Online (Sandbox Code Playgroud)\r\n我想要I3 output那时I4 output。为什么这不起作用?
我的目标是防止所有者以外的其他用户修改/读取权限。在ubuntu论坛上,对两种方法都给出了评论。
例:
sudo useradd -d /home/newuser -m newuser;
sudo chmod 700 /home/newuser # or # chmod go-rwx /home/newuser
Run Code Online (Sandbox Code Playgroud)
=> chmod go-rwx和/ chmod 700或两者完成相同的事情之间是否有区别?如果存在差异,建议使用哪一个?
我正在努力理解移动和右值转换之间显示的不同行为
给出:
template <class T> void f1(T param) { }
struct B { B() = default; B(B&&) { cout << "Move constructor\n"; } };
void demo()
{
f1(static_cast<B&&>(B())); // does not call move constructor - constructor is elided
f1(move(B())); // calls move constructor - no elision
}
Run Code Online (Sandbox Code Playgroud)
移动调用强制调用移动构造函数,而静态转换则不会,并且构造函数显然被省略了。这看起来很奇怪,因为 std::move 的定义看起来很像静态转换。
为什么会有不同的行为?
更新:不能用 gcc 复制。仅使用 MSVC 显示的行为
让我们保存一下,我有这段代码,它显示线程读取过时的缓存,这会阻止它退出 while 循环。
class MyRunnable implements Runnable {
boolean keepGoing = true; // volatile fixes visibility
@Override public void run() {
while ( keepGoing ) {
// synchronized (this) { } // fixes visibility
// Thread.yield(); // fixes visibility
System.out.println(); // fixes visibility
}
}
}
class Example {
public static void main(String[] args) throws InterruptedException{
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();
Thread.sleep(100);
myRunnable.keepGoing = false;
}
}
Run Code Online (Sandbox Code Playgroud)
我相信Java内存模型保证对易失性变量的所有写入与任何线程的所有后续读取同步,从而解决了问题。
如果我的理解是正确的,同步块生成的代码也会清除所有挂起的读取和写入,这充当一种“内存屏障”并解决问题。
从实践中我发现插入yield并且println还使变量更改对线程可见并且它正确退出。我的问题是:
Yield/println/io 作为 JMM 以某种方式保证的内存屏障,还是幸运的副作用,无法保证有效? …
python中有没有办法将泛型类型限制为可以实例化的类型?
我正在寻找与 C# 相当的东西
where T : new()
Run Code Online (Sandbox Code Playgroud)
我已经在使用类型提示,如下所示
T = TypeVar("T", bound=Button)
Run Code Online (Sandbox Code Playgroud)
我想知道是否有类似的东西
T = TypeVar("T", bound=Button,new())
Run Code Online (Sandbox Code Playgroud)
例如,假设 Button 是一个抽象类 (ABC),此代码应创建一个由 Button 的任何子类型组成的菜单
class Button(ABC):
def __init__(self) -> None:
self._name = ""
@abstractmethod
def show(self) -> None:
pass
def set_name(self, value:str) -> None:
self._name = value
class SquareButton(Button):
def show(self) -> None:
print("[",self._name,"]")
class CircleButton(Button):
def show(self) -> None:
print("(",self._name,")")
T = TypeVar("T", bound=Button) # restricting type here
class MenuBuilder:
def build(self,class_type: Type[T]) -> None:
pb1: Button = class_type() …Run Code Online (Sandbox Code Playgroud) java ×4
c++ ×3
c++20 ×2
c++-concepts ×1
c++23 ×1
caching ×1
chmod ×1
filesystems ×1
generics ×1
interception ×1
javascript ×1
proxy ×1
python ×1
spring ×1
static ×1
templates ×1
unix ×1