System.out.println("嘿,明白了......");从未在我的程序中执行过
由于synchronized关键字,我可以理解它,但实际上发生了什么。
从 CFG 类调用 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);
}
}
}
}
主类执行从这里开始
public class GFG{
public static void main (String[] args){
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Bye Bye");
}
});
new Thread(new TestJoin("1")).start();
new Thread(new TestJoin("1")).start();
new Thread(new TestJoin("2")).start();
new Thread(new TestJoin("3")).start();
}
}
上述执行的输出
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
第二次编辑:
仅当我与字符串或单例对象同步时才会出现上述问题, 如果我使用一个新对象它的完美文件
示例,使用普通对象同步
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
最佳答案
这是因为字符串常量是实习的,所以当您在 ThreadJoining
和 TestJoin
中同步 "2"
时,您实际上是在锁定同一个对象。
当 new TestJoin("2")
锁定 "2"
然后等待 new ThreadJoining("2")< 时,这会导致死锁
完成(这永远不会发生,因为它无法获得 "2"
上的锁定)。
关于java - 线程与单例对象或字符串的同步连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51852811/