我有两个线程thread1(打印号码)& thread2(打印字母)。 我的目标是通过同步化获得以下输出:
1 一个 2 b 3 C 4 d 五 ë
class thread1 implements Runnable {
public void run() {
try {
for (int i = 1; i <= 5; i++) {
System.out.println("Is Thread1 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
synchronized (Testing.class) {
System.out.println("Is Thread1 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
try {
System.out.println(i);
Testing.class.notifyAll();
System.out.println("Thread1:Going to wait");
Testing.class.wait();
System.out.println("Thread1:Resuming from wait");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Finsihed thread1");
} catch (Exception e) {
System.out.println(e);
}
}
}
class thread2 implements Runnable {
char[] alphabets = { 'a', 'b', 'c', 'd', 'e' };
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println("Is Thread2 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
synchronized (Testing.class) {
try {
System.out.println("Is Thread2 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
System.out.println("Thread2:Going to wait");
Testing.class.wait();
System.out.println("Thread2:Resuming from wait");
System.out.println(alphabets[i]);
Testing.class.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
public class Testing {
public static void main(String[] args) {
Testing w= new Testing();
thread1 t1 = new thread1();
thread2 t2 = new thread2();
Thread th1 = new Thread(t1, "");
Thread th2 = new Thread(t2, "");
try {
th1.start();
th2.start();
} catch (Exception e) {
System.out.println(e);
}
}
}
我收到了输出:
Thread1是否持有锁 Testing.class:假
Thread1是否持有锁 Testing.class:真
1
线程1:要等待
Thread2是否持有锁 Testing.class:假
Thread2是否持有锁 Testing.class:真
线程2:要等待
如果thread2已被thread1锁定,那么thread2如何获得了Testing.class的锁定?此外,有没有其他优雅的方式来实现这种同步?提前谢谢。
答案 0 :(得分:1)
详细了解Java Concurrency。
调用wait
会释放锁定。
答案 1 :(得分:1)
当您调用wait()
方法时,您调用它的线程会暂时放弃锁定。因此,当thread1在wait()
方法内等待时,它没有持有锁,而thread2可以获得锁。
当wait()
方法返回时,线程将再次保持锁定。
班级wait()
中Object
方法的API文档详细说明了这一点。
答案 2 :(得分:0)
您遇到的基本问题是释放同步块,允许两个线程同时通过循环。这意味着任何一个线程都可以按任何顺序获取锁定。
AFAIK,最简单的解决方案是使用旗帜。
final int length = 10;
final AtomicBoolean flag = new AtomicBoolean();
new Thread(new Runnable() {
public void run() {
for (int i=1;i<=length;i++) {
while(flag.get());
System.out.print(i+" ");
flag.set(true);
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (char c='a';c<'a'+length;c++) {
while(!flag.get());
System.out.print(c+" ");
flag.set(false);
}
System.out.println();
}
}).start();
同步完成此任务的最优雅方法是拥有一个线程。线程专门设计用于执行两个任务,它们之间尽可能不依赖。
顺便说一句
如果在调用wait()之前调用notifyAll(),则通知将丢失。 wait()将永远等待。
您创建一个丢弃的测试对象(将其删除)。
你捕获InterruptedException,你打印并继续,好像什么都没发生(即删除嵌套的catch)
答案 3 :(得分:0)
这是完整的工作代码
公共类MyClass
{
MyClass mClass;
public void doTest()
{
final int [] a = {1,2,3,4,5,6,7,8,9,10};
final char [] c = {'a','b','c','d','e','f','g','h','i','j'};
mClass = this;
Thread t1 = new Thread(new Runnable(){
public void run()
{
for(int i = 0 ; i<a.length ; i++)
{
synchronized(mClass)
{
System.out.print(a[i]+" ");
mClass.notify();
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable(){
public void run()
{
for(int i = 0 ; i<c.length ; i++)
{synchronized(mClass)
{
System.out.print(c[i]+" ");
mClass.notify();
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t2.start();
} public static void main(String [] ar) {
new MyClass().doTest();
}
}
答案 4 :(得分:0)
公共类MyClass { MyClass mClass; boolean isFirstStartedRunning = true; public void doTest() { final int [] a = {1,2,3,4,5,6,7,8,9,10}; final char [] c = {'a','b','c','d','e','f','g','h','i','j'}; mClass = this; 线程t1 =新线程(新的Runnable(){
public void run()
{
isFirstStartedRunning = false;
for(int i = 0 ; i<a.length ; i++)
{
synchronized(mClass)
{
System.out.print(a[i]+" ");
mClass.notify();
if(i==a.length-1)return;
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable(){
public void run()
{
if(isFirstStartedRunning){
try{mClass.wait();}catch(Exception e){}
}
for(int i = 0 ; i<c.length ; i++)
{
synchronized(mClass)
{
System.out.print(c[i]+" ");
mClass.notify();
if(i==a.length-1)return;
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t2.start();
} public static void main(String [] ar) {
new MyClass().doTest();
}
} 现在检查答案