我试图理解倒计时锁的用法,下面是我在这里使用的代码,
可递减.java
package com.nirjhar.java.countdownlatchexample;
import java.util.concurrent.CountDownLatch;
public class DecrementRunnable implements Runnable {
private String name;
private CountDownLatch cdl;
public DecrementRunnable(String name, CountDownLatch cdl) {
this.name=name;
this.cdl=cdl;
}
@Override
public void run() {
System.out.println("in run method");
for (int i = 0; i < 6; i++) {
cdl.countDown();
System.out.println("counting down "+cdl.getCount());
}
//cdl.notifyAll();
System.out.println("Notified to all");
}
}
倒计时线程.java
package com.nirjhar.java.countdownlatchexample;
import java.util.concurrent.CountDownLatch;
public class CountDownDemoThread extends Thread {
private CountDownLatch cdl;
public CountDownDemoThread(String name, CountDownLatch cdl) {
this.cdl=cdl;
setName(name);
}
@Override
public synchronized void start() {
System.out.println("Task completed ... waiting for other thread to complete their task");
try {
cdl.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Continuing my tasks ..");
}
}
主程序,
package com.nirjhar.java.countdownlatchexample;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args)
{
CountDownLatch cdl=new CountDownLatch(6);
Thread tDecrementThread=new Thread(new DecrementRunnable("Runnable", cdl));
CountDownDemoThread cddt=new CountDownDemoThread("thread", cdl);
cddt.start();
System.out.println("thread 1 started");
tDecrementThread.start();
}
}
在这个主程序中,我希望一旦线程1启动,就应该打印这一行“thread1started”,但是由于cddt thread的cdl.await()语句中的wait语句,主线程被阻塞了。只是想知道这背后的原因是什么?
9条答案
按热度按时间cl25kdpy1#
在你的
CountDownThread
同学们,我想你们想推翻run()
方法而不是start
而不是公共同步void start(){
尝试
public void run(){
为什么
cdl中的wait语句。cddt线程中的await()语句。只是想知道这背后的原因是什么?
在这种情况下,您已经覆盖了
start
方法Thread
因此它不再像平常那样生成线程来执行代码。因此,没有线程生成并影响
main
线程正在调用cd1.await()
而不是cd1
线程(你想要的)。这就是为什么main
线程被阻塞。cgh8pdjw2#
我认为您应该了解线程同步和线程优先级的概念。
1.线程优先级:
java中的每个线程都有一定的优先级—可以是jvm生成的默认优先级,也可以是程序员提供的自定义优先级—线程优先级的有效范围是1到10,其中1是最小优先级,10是最大优先级—thread class定义了以下常量来表示一些标准优先级:
1.thread.min\u优先级
lnvxswe23#
-------1
2.thread.norm\u优先级
uqdfh47h4#
------5
3.thread.max\u优先级
mlmc2os55#
-------10
线程调度程序将在分配处理器时使用优先级具有最高优先级的线程将首先获得机会如果两个线程具有相同的优先级,那么我们不能期望确切的执行顺序它取决于线程调度程序
thread类定义以下方法来获取和设置线程的优先级:
1.public final int getpriority()
2.公共最终无效设置优先级(int p)
note:allowed values 范围从1到10,否则我们将得到运行时异常illegalargumentexception
例如:t.setpriority(7):有效
t、 设置优先级(17):illegalargumentexception
wgxvkvu96#
默认优先级
bvjveswy7#
仅主线程的默认优先级为5,但对于所有剩余线程,默认优先级将从父线程继承到子线程,即父线程的优先级与子线程的优先级相同
oxiaedzo8#
------自定义优先级
qlvxas9a9#
如果我们注解第1行,那么主线程和子线程都具有相同的优先级5,因此我们不能期望执行顺序和确切的输出如果不注解第1行,那么主线程具有优先级5,子线程具有优先级,因此子线程将有机会先获得主线程,然后获得主线程。在这种情况下,输出为:
2.同步:
synchronized是仅适用于方法和块的修饰符,但不适用于类和变量。
如果多个线程试图在同一个java对象上同时操作,那么就有可能出现数据不一致的问题。
为了克服这个问题,我们应该使用synchronized关键字如果一个方法或块声明为synchronized,那么一次只允许一个线程在给定的对象上执行该方法或块,这样数据不一致的问题就会得到解决。
synchronized关键字的主要优点是可以解决数据不一致的问题,但是synchronized关键字的主要缺点是它增加了线程的等待时间,并且会产生性能问题,因此如果没有特定的要求,则不建议使用synchronized关键字。
内部同步的概念是用锁来实现的,java中的每个对象都有一个唯一的锁。
每当我们使用同步关键字,那么只有锁的概念将进入图片。
如果一个线程想首先在给定对象上执行synchronized方法,它必须获得该对象的锁。
一旦线程获得了锁,就可以对该对象执行任何同步方法。
一旦方法执行完成,线程就会自动释放锁。在内部获取和释放锁由jvm和一个不负责此活动的程序员负责
当一个线程在给定对象上执行同步方法时,不允许其余线程在同一对象上同时执行任何同步方法,但允许其余线程同时执行非同步方法
例子:
在上面的示例中,假设线程t1开始执行m1(),因为t1首先从jvm访问锁,如果同时线程t2来执行m1()方法,线程t3来执行m2()方法,那么此时线程t2和t3都将处于等待状态,直到t1线程释放锁。
如果线程t4来执行m3()方法,它将直接执行m3()方法,因为它不是同步方法。锁的概念是基于对象实现的,而不是基于方法实现的
注意:记住每个对象都有两个区域:
1.同步区域。
2.非同步区域。
示例:程序方法:
[注意:如果我们没有将wish(字符串名称)方法声明为synchronized,那么所有线程都将同时执行,因此我们将得到不规则的输出。
如果我们声明wish(string name)方法为synchronized,那么一次只允许一个线程在给定的display(class)对象上执行wish(string name)方法,因此我们将获得常规输出。]
案例研究:
即使wish(string name)方法是同步的,我们也会得到不规则的输出,因为线程在不同的java对象上操作
结论:
如果多个线程在同一个java对象上运行,则需要同步。
如果多个线程在多个java对象上运行,则不需要同步。
java中的每个类都有一个唯一的锁,它只不过是类级锁。
如果线程想要执行静态同步方法,那么线程需要类级锁。
一旦线程获得了类级锁,就可以执行该类的任何静态同步方法。
方法执行完成后,当线程执行静态同步方法时,线程自动释放锁,不允许剩余线程同时执行该类的任何静态同步方法,但允许剩余线程同时执行以下方法:
常规静态法。
同步示例方法。
普通示例方法。
例如: