我是java线程的新手。我无法在以下代码中将锁定从主线程返回给线程。我得到了不受欢迎的输出,因为我无法解锁线程。我希望线程使用线程递增值(之后进入等待状态)并在打印值后,释放锁以打印下一个递增的值。
class Foo implements Runnable
{
public volatile int value=0,i=0;
Thread t=new Thread();
public void method(Thread t)
{
this.t = t;
}
@Override
public synchronized void run()
{
while(i<3)
{
value++;//receive and process ACK
i++;
try
{
System.out.println("im thread here");
wait();
System.out.println("passed wait");
}
catch(InterruptedException ex){
}
System.out.println("im notified");
}//while
//}//sync
}//run method
public int getValue()
{
try
{
Thread.sleep(1000);
}
catch (Exception e) {
System.out.println(e);
}
return value;
}
}//class foo
public class ThreadTest
{
public static int value1,times=0;
public static void main(String[] args)
{
Foo foo=new Foo();
Thread t=new Thread(foo);
foo.method(t);
t.start();
while(times<3)
{
synchronized(t)
{
value1=foo.getValue();
times++;
System.out.println(value1);
System.out.println(t.getState());
try
{
t.notify();
System.out.println("Notify is reached");
}
catch(IllegalMonitorStateException ex)
{
System.out.println("Thread is blocked");
}
}//sync
}//while
}//main
}//mclasss
答案 0 :(得分:0)
目前还不清楚你真正想做什么,但是我们假设你想在后台运行一个线程,该线程只有在它的生成器(让主线程允许)允许的情况下才能运行。
JDK已经有了几个工具,不需要依赖低级wait()和notify {,All}()方法。
这种原语的一个例子是CountDownLatch
。它是一个一次性使用的实体,允许您在任何线程countDown()
触发之前指定给定线程集应该.await()
的时间。
结合早在Java 1.5中出现的多线程处理类,这意味着您可以执行以下操作:
// Implementation of a Runnable waiting for the counter to trigger
public final class MyWaitingClass
implements Runnable
{
private final CountDownLatch latch;
public MyWaitingClass(final CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
try {
latch.await();
// do whatever is necessary
} catch (InterruptedException e) {
// Argh; interrupted before the latch was released
Thread.currentThread().interrupt();
}
}
}
// In the main class:
final ExecutorService executor = Executors.newSingleThreadPool();
final CountDownLatch latch = new CountDownLatch(1);
final Runnable runnable = new MyWaitingClass(latch);
executor.submit(runnable);
// do whatever is needed; then:
latch.countDown();
答案 1 :(得分:0)
我添加了一个等待块,否则主线程可能会在后台线程增加值之前完成。
class Foo implements Runnable {
public volatile int value = 0, i = 0;
private Thread backgroundThread;
public void setThread(Thread thread) {
this.backgroundThread = thread;
}
@Override
public void run() {
synchronized (backgroundThread) {
while (i < 2) {
value++;
i++;
backgroundThread.notify();
try {
System.out.println("background thread wait start");
backgroundThread.wait();
System.out.println("background thread notified");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
public int getValue() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}
public class ThreadTest {
public static int value1, times = 0;
public static void main(String[] args) {
Foo foo = new Foo();
final Thread thread = new Thread(foo);
foo.setThread(thread);
thread.start();
while (times < 3) {
synchronized (thread) {
value1 = foo.getValue();
times++;
System.out.println(value1);
System.out.println(thread.getState());
thread.notify();
try {
thread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
或者你可以扩展线程:
class BackgroundThread extends Thread {
public volatile int value = 0, i = 0;
@Override
public synchronized void run() {
while (i < 2) {
value++;
i++;
notify();
try {
System.out.println("background thread wait start");
wait();
System.out.println("background thread notified");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public int getValue() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}
public class ThreadTest {
public static int value1, times = 0;
public static void main(String[] args) {
BackgroundThread backgroundThread = new BackgroundThread();
backgroundThread.start();
while (times < 3) {
synchronized (backgroundThread) {
value1 = backgroundThread.getValue();
times++;
System.out.println(value1);
System.out.println(backgroundThread.getState());
backgroundThread.notify();
try {
backgroundThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}