java多线程
请教大家两个图中的问题
一、下图中 主线程中有两个子线程,为什么红圈标记的System.out.println 全部没有执行呢,而且第一行输出还丢失了前面一部分
二、下图中出现了好多我不理解的问题
2.1、为什么将run 中循环删除list的代码注释掉以后图一中的控制台输出全部打印出来了。
2.2、为什么线程类中synchronized(list) 这个锁为什么必须使用 list 下图控制台输出可以看到 不管是this 还是list 输出的hashcode 值都是一样的(这里发现用不同构造方法new 出来的线程对象hashcode是相对相等的,按道理不管是否是相同够着方法,每次构造出来的类 this.hashcode 不应该相等才对啊这又是为什么呢),回到线程锁为什么用this 作为锁不行,按道理来说锁的对象只要是相等的就是会锁住用“1”也是可以的,那为什么用相等的this。hashcode不行,而list.hashcode又可以
2.3、list1.hashcode 是不一样的,因为主线程是new 了两次线程类 被创建了两次,而list由于被构造方法赋值,主线程中传递的是同一个list 所以hashcode是同一个我还能理解,但是为什么list1.hashcode 也是相等的 为1 下图中没有输出为了看第四个问题的日志
2.4、可以看到run中最后一行输出是System.out.println(name+"list="+list.hashCode()); 这行代码进行了报错提示 Exception in thread "Thread-1" Exception in thread "Thread-0" java.lang.NullPointerException,这里为什么加了name线程名称就会报空 而上面一行System.out.println("list="+list.hashCode());这行不加name 同样输出 list.hashcode 不会报错呢
线程操作不能保证原子性
【以下回答由 GPT 生成】
问题一中红圈标记的System.out.println没有执行,并且第一行输出丢失了前面一部分,是因为在主线程中启动了两个子线程,但是主线程并不会等待子线程执行完毕再退出,而是直接退出了,因此子线程中的代码没有机会执行完毕。
要解决这个问题,可以使用Thread.join方法,使得主线程等待子线程执行完毕再退出。具体步骤如下:
下面是示例代码:
public class MainThread {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
// 子线程1的代码逻辑
System.out.println("子线程1执行");
});
Thread t2 = new Thread(() -> {
// 子线程2的代码逻辑
System.out.println("子线程2执行");
});
t1.start();
t2.start();
t1.join(); // 等待子线程1执行完毕
t2.join(); // 等待子线程2执行完毕
System.out.println("主线程执行");
}
}
问题二的几个问题的解答如下:
2.1、将run中循环删除list的代码注释掉之后,图一中的控制台输出全部打印出来了。这是因为删除了对list的操作,不会引起多线程下的同步问题,因此控制台输出正常。
2.2、线程类中synchronized(list)这个锁必须使用list。使用synchronized关键字时,锁住的是对象,而不是对象的引用。在这里,使用list作为锁可以保证对list的操作是互斥的,因为多个线程使用的是同一个list对象。
2.3、list1.hashcode的值为1,是因为主线程中new了两次线程类,每次new都会创建一个新的对象,因此list1和list是不同的对象,它们的hashcode值会不同。
2.4、在run方法中最后一行代码System.out.println(name + "list=" + list.hashCode())报错提示NullPointerException,是因为name为null造成的。当使用name作为参数传递给Thread的构造方法时,name的值为null,导致在打印输出时出现NullPointerException。而上面一行代码System.out.println("list=" + list.hashCode())不报错是因为没有使用name变量,没有使用null值。
综上所述,问题的解答如下:
问题一中红圈标记的System.out.println没有执行,并且第一行输出丢失了前面一部分,是因为主线程退出时未等待子线程执行完毕。解决方法是使用Thread.join方法让主线程等待子线程执行完毕再退出。
问题二的几个问题的解答是: - 2.1、注释掉删除list的代码后,控制台输出正常,因为没有引起多线程下的同步问题。 - 2.2、synchronized关键字锁住的是对象,多个线程使用的是同一个list对象。 - 2.3、list1和list是不同的对象,因此它们的hashcode值不同。 - 2.4、使用name作为参数传递给Thread的构造方法,当name为null时会导致NullPointerException。不使用name变量就不会出现该错误。