Java线程同步-Thread.sleep()方法未按预期工作
我听说,sleep()将锁定当前的同步方法/块 但是在这里,当我在线程1上调用sleep()时,线程2能够访问相同的块吗?有人能解释一下吗 主类 ===================================================================== Thread1.java ===================================================================== Thread2.java ===================================================================== Syncc.java 但是根据sleep()方法,它不应该解锁当前的同步块,对吗?如果是这样的话,输出应该是 要开始t1吗 要开始t2吗Java线程同步-Thread.sleep()方法未按预期工作,java,multithreading,synchronization,sync,Java,Multithreading,Synchronization,Sync,我听说,sleep()将锁定当前的同步方法/块 但是在这里,当我在线程1上调用sleep()时,线程2能够访问相同的块吗?有人能解释一下吗 主类 ===================================================================== Thread1.java ===================================================================== Thread2.java ===========
T1: 0
T1: 1
T1: 2
T1: 3
T1: 4
T1: 5
T2: 0
T2: 1
T2: 2
T2: 3
T2: 4
T2: 5
我的意思是在线程1执行之后,只有线程2应该正确启动?
什么问题 这是因为这里有两个不同的
Syncc
实例。每个线程都有自己的Syncc
副本
public class Thread1 extends Thread {
private Syncc syncc;
public Thread1(Syncc syncc) {
this.syncc = syncc;
}
public void run() {
this.syncc.me("T1:");
}
}
尝试对单个实例执行相同的操作。您还可以在静态上下文上进行同步,然后重试
要进行模拟,请修改Thread1
和Thread2
以接受Syncc
的实例
public class Thread1 extends Thread {
private Syncc syncc;
public Thread1(Syncc syncc) {
this.syncc = syncc;
}
public void run() {
this.syncc.me("T1:");
}
}
然后,您可以按如下方式启动它们:
public static void main(String args[]) {
Syncc syncc = new Syncc();
Thread1 t1 = new Thread1(syncc);
Thread2 t2 = new Thread2(syncc);
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
睡眠、屈服和加入的规则
- 睡眠用于将执行延迟一段时间,并且不使用锁 当线程进入睡眠状态时释放
- 保证休眠线程至少在中指定的时间内休眠 sleep()方法的参数(除非它被中断),但是 无法保证新唤醒的线程何时实际返回 正在运行。
- sleep()方法是一个静态方法,用于睡眠当前正在执行的 线程的状态。一个线程不能告诉另一个线程睡眠
- setPriority()方法用于线程对象以提供线程 优先级介于1(低)和10(高)之间,尽管优先级不是 保证,但并非所有JVM都能识别10个不同的优先级 水平可被视为有效相等
- 如果未显式设置,线程的优先级将与 创建它的线程的优先级
- 如果存在,yield()方法可能会导致正在运行的线程退出 具有相同优先级的可运行线程。不能保证这会发生 当线程返回时,无法保证 将选择一个不同的线程来运行。一根线可能会屈服,然后 立即重新进入运行状态
- 最接近于保证的是,在任何给定的时间,当线程 在运行时,它的优先级通常不会低于 可运行状态。如果低优先级线程正在运行,而高优先级线程正在运行 进入runnable,JVM通常会抢占正在运行的低优先级 线程并将高优先级线程放入
- 当一个线程调用另一个线程的join()方法时,当前 正在运行的线程将等待它所连接的线程完成。思考 对join()方法的解释是:“嘿,线程,我想连接到底 谢谢你。完成后请告诉我,这样我就可以进入可运行状态。”
您已经创建了两个同步对象,每个对象对应一个线程。每个对象都有自己的“我”副本。因此,当您启动每个线程时,使用run方法,线程正在调用自己的函数me副本。由于两个线程只作用于它们的副本,因此这类似于单线程场景。如果您确实想测试多线程场景,那么将方法me设置为静态(类级方法),并应用类级锁 Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
public class Syncc{
public static void me(String s){
synchronized(Syncc.class){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread2.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
public class Syncc{
public static void me(String s){
synchronized(Syncc.class){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Syncc.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
public class Syncc{
public static void me(String s){
synchronized(Syncc.class){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
公共类同步{
公共静态void me(字符串s){
已同步(Syncc.class){
对于(int i=0;iThread1和Thread2使用不同的Syncc实例,因此它们访问两个不同Syncc实例的方法me(),所以同步块不起作用。明白了,非常感谢lotz adarshr。现在我可以开始了,再次感谢。adarshr您能告诉我如何调用notify()我的意思是我需要用thread1打印1-3,然后thread1必须去等待()现在thread2应该打印所有5个数字,然后再打印thread1需要打印剩余的…实际上我对threads是新手,我在网上看到了很多例子,但有很多困惑,但是你的解释真的很好,我理解了这个概念,请做这个帮助谢谢。