Java 线程连接与单例对象或sting的同步
System.out.println(“嘿,明白了……”);在我的程序中从未执行过 我可以理解它是因为synchronized关键字,但实际上发生了什么 从CFG类调用TestJoin类,问题出在这个类中Java 线程连接与单例对象或sting的同步,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,System.out.println(“嘿,明白了……”);在我的程序中从未执行过 我可以理解它是因为synchronized关键字,但实际上发生了什么 从CFG类调用TestJoin类,问题出在这个类中 class TestJoin implements Runnable{ public String x; TestJoin(String x){ this.x= x; } public void testJoin() {
class TestJoin implements Runnable{
public String x;
TestJoin(String x){
this.x= x;
}
public void testJoin() {
System.out.println("b4"+x);
synchronized(x) {
System.out.println(x);
ThreadJoining t1 = new ThreadJoining("2");
// thread t1 starts
t1.start();
System.out.println("you fool");
try{
System.out.println(
"Current Thread: "+
Thread.currentThread().getName()
);
t1.join();
//never this line is executed
System.out.println("hey got it....");
}catch(Exception ex){
System.out.println(
"Exception has " +
"been caught" + ex
);
}
}
}
@Override
public void run() {
testJoin();
}
}
只需创建另一个从TestJoin类调用的线程
class ThreadJoining extends Thread{
String c;
ThreadJoining(String co){
c=co;
}
@Override
public void run()
{
synchronized(c) {
for (int i = 0; i < 2; i++){
try{
Thread.sleep(500);
System.out.println(
"Current Thread: " +
Thread.currentThread().getName()
);
}catch(Exception ex){
System.out.println(
"Exception has" +
" been caught" + ex
);
}
System.out.println(i);
}
}
}
}
上述执行的输出
b41
1
b43
3
b42
2
b41
you fool
Current Thread: Thread-4
you fool
Current Thread: Thread-1
you fool
Current Thread: Thread-3
第二次编辑:
上述问题仅在我与string或singleton对象同步时出现,
如果我使用一个新对象,它的文件
例如,使用普通对象同步
public class GFG{
public static void main (String[] args){
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Bye Bye");
}
});
Sample s = new Sample();
new Thread(new TestJoin(s)).start();
new Thread(new TestJoin(s)).start();
new Thread(new TestJoin(new Sample())).start();
new Thread(new TestJoin(new Sample())).start();
}
}
public class TestJoin implements Runnable{
public Sample x;
TestJoin(Sample x){
this.x= x;
}
public void testJoin() {
System.out.println("b4"+x);
synchronized(x) {
System.out.println(x);
ThreadJoining t1 = new ThreadJoining("2");
// thread t1 starts
t1.start();
System.out.println("you fool");
try
{
System.out.println("Current Thread: "
+ Thread.currentThread().getName());
t1.join();
System.out.println("hey got it....");
}
catch(Exception ex)
{
System.out.println("Exception has " +
"been caught" + ex);
}
}
}
@Override
public void run() {
testJoin();
}
}
class ThreadJoining extends Thread{
String c;
ThreadJoining(String co){
c=co;
}
@Override
public void run(){
synchronized(c) {
for (int i = 0; i < 2; i++){
try{
Thread.sleep(500);
System.out.println(
"Current Thread: " +
Thread.currentThread().getName()
);
}catch(Exception ex){
System.out.println(
"Exception has" +
" been caught" + ex
);
}
System.out.println(i);
}
}
}
}
public class Sample {
}
这是因为字符串常量是内部的,所以在
threadjoin
和TestJoin
中的“2”
上同步时,实际上锁定的是同一个对象
当
newtestjoin(“2”)
锁定“2”
,然后等待newthreadjoin(“2”)
完成时(这永远不会发生,因为它无法锁定“2”
)。这是因为字符串常量被插入,所以在“2”上同步
在threadjoin
和TestJoin
中,您实际上锁定了同一个对象
当
newtestjoin(“2”)
锁定“2”
然后等待new threadjoin(“2”)
完成时,这会导致死锁(这永远不会发生,因为它无法获得“2”
上的锁定).在String
上进行同步不是一个好主意,这是一个轻描淡写的说法。但即使我与singleton对象同步,同样的问题也会发生,但当我创建一个新对象时,它工作正常。对我来说,这看起来像是一个死锁。您的一个TestJoin1持有锁,而另一个仍在等待其线程连接完成(在其运行的顶部也需要相同的锁)。或者类似的。尝试kill-QUIT
查看线程转储以及它们持有和等待的锁。查看String
上的同步不是一个好主意,这是一个轻描淡写的说法。但即使我与singleton对象同步,同样的问题也会发生,但当我创建一个新对象时,它工作正常。在我看来,这是一个死锁。您的一个TestJoin1持有锁,而另一个仍在等待其线程连接完成(在其运行的顶部也需要相同的锁)。或者类似的。尝试一个kill-QUIT
来查看线程转储以及它们持有和等待的锁。请参阅
public class GFG{
public static void main (String[] args){
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Bye Bye");
}
});
Sample s = new Sample();
new Thread(new TestJoin(s)).start();
new Thread(new TestJoin(s)).start();
new Thread(new TestJoin(new Sample())).start();
new Thread(new TestJoin(new Sample())).start();
}
}
public class TestJoin implements Runnable{
public Sample x;
TestJoin(Sample x){
this.x= x;
}
public void testJoin() {
System.out.println("b4"+x);
synchronized(x) {
System.out.println(x);
ThreadJoining t1 = new ThreadJoining("2");
// thread t1 starts
t1.start();
System.out.println("you fool");
try
{
System.out.println("Current Thread: "
+ Thread.currentThread().getName());
t1.join();
System.out.println("hey got it....");
}
catch(Exception ex)
{
System.out.println("Exception has " +
"been caught" + ex);
}
}
}
@Override
public void run() {
testJoin();
}
}
class ThreadJoining extends Thread{
String c;
ThreadJoining(String co){
c=co;
}
@Override
public void run(){
synchronized(c) {
for (int i = 0; i < 2; i++){
try{
Thread.sleep(500);
System.out.println(
"Current Thread: " +
Thread.currentThread().getName()
);
}catch(Exception ex){
System.out.println(
"Exception has" +
" been caught" + ex
);
}
System.out.println(i);
}
}
}
}
public class Sample {
}
b4Sample@a5c4778
b4Sample@27efa2ad
b4Sample@a5c4778
b4Sample@27507837
Sample@27507837
Sample@27efa2ad
Sample@a5c4778
you fool
you fool
Current Thread: Thread-4
you fool
Current Thread: Thread-3
Current Thread: Thread-1
Current Thread: Thread-6
0
Current Thread: Thread-6
1
hey got it....
Current Thread: Thread-5
0
Current Thread: Thread-5
1
hey got it....
Current Thread: Thread-7
0
Current Thread: Thread-7
1
hey got it....
Sample@a5c4778
you fool
Current Thread: Thread-2
Current Thread: Thread-8
0
Current Thread: Thread-8
1
hey got it....
Bye Bye