我有一个关于静态同步方法和类级别锁定的问题。 有人可以帮我解释这个例子:
class Test
{
synchronized static void printTest(int n)
{
for (int i = 1; i <= 10; i++) {
System.out.println(n * i);
try {
Thread.sleep(400);
} catch (Exception ignored) {}
}
}
}
class MyThread1 extends Thread
{
public void run()
{
Test.printTest(1);
}
}
class MyThread2 extends Thread
{
public void run()
{
Test.printTest(10);
}
}
public class TestSynchronization
{
public static void main(String[] args)
{
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t1.start();
t2.start();
}
}
当线程t1
处于循环中间(printTest()
内)时,我想让它停止执行并将控制转移到线程t2
。
有没有办法做到这一点?
由于我们处理类级锁定,我相信我们不能在这里使用对象级别wait()
和notify()
方法来释放对象级锁定。但是在类级别锁定的情况下,如何释放它并将控件提供给其他一些等待的线程?
我们如何通知第二个线程在执行过程中等待线程1持有的类级锁定?
答案 0 :(得分:1)
interrupt()
可以在这里用于您的要求。
如果您的需求将来发生变化,并且在第二个线程之后需要执行第一个线程,则删除if(Thread.interrupted())
内的printTest
class Test {
synchronized static void printTest(int n) {
for (int i = 1; i <= 10; i++) {
if(Thread.interrupted())
break;
System.out.println(n * i);
try {
Thread.sleep(400);
} catch (Exception e) {
}
}
}
}
class MyThread1 extends Thread {
public void run() {
Test.printTest(1);
}
}
class MyThread2 extends Thread {
public void run() {
Test.printTest(10);
}
}
public class TestSynchronization {
public static void main(String t[]) throws InterruptedException {
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t1.start();
t2.start();
t1.interrupt();
t1.join();
}
}
答案 1 :(得分:1)
由于我们处理类级别锁定,我认为我们无法使用对象级别
wait()
和notify()
我尽量避免说“班级”或“对象级别”。无论何时使用synchronized
,您都在同步某个对象。请记住:Test.class
是对象:它是包含描述Test
类的所有运行时信息的对象。
当你说“类级锁定”时,你真正在谈论的是在全局单例对象(类对象)上进行同步,而不是“实例级锁定”该类的许多不同实例可以独立synchronized
。
我想让它停止执行并将控制转移到线程t2。
这不是考虑线程的非常有用的方法。您通常不希望程序中的某个线程等待轮到其执行某项任务:您希望它等待自己的任务。线程总是需要某些来协调和相互沟通,但是你能够让每个线程做更多的事情,你会更好地利用它们。
您不希望将“转移控制”从一个线程转移到另一个线程,而是希望每个线程始终控制自己的事物。
我们如何通知正在等待锁定的第二个线程?
nothing 可以释放线程等待进入synchronized
块。这是synchronized
的限制之一,这也是为什么任何线程永远停留在synchronized
块中比更新几个字段更长的一个原因之一。< / p>
我想让它停止执行
引起循环线程注意的最简单方法是让线程每次循环检查volatile boolean
变量的值。
volatile boolean timeToStop = false;
MyType myMethod(...) {
while (! timeToStop) {
...
}
}
然后,任何其他线程都可以设置timeToStop=true;
以获得第一个线程的注意。
答案 2 :(得分:0)
来自你的评论:
有一个线程(t2)在另一个线程(t1)持有的类级锁上等待。因此,t1线程可以在t1退出静态同步方法之前通知线程t2。
是的,类是对象,只需调用notify()
。
class Test
{
synchronized static void printTest( int n )
{
for( int i = 1; i <= 10; i++ ) {
System.out.println( n * i );
}
try {
Test.class.notify(); // just use a class literal
} catch( Exception ignored ) {
}
}
}