我试图用两个线程打印数字1-20:
我还有一个用于同步的锁定对象。
我的申请被卡住了。你能告诉我这是什么问题吗?
我的代码:
public class runIt
{
public static void main(String[] args)
{
Odd odd = new Odd("odd thread");
Even even = new Even("even thread");
odd._t.start();
even._t.start();
try{
odd._t.join();
even._t.join();
}
catch (InterruptedException e){
System.out.println(e.getMessage());
}
}
}
public class Constants{
static Object lock = new Object();
}
public class Even implements Runnable{
Thread _t;
String _threadName;
public Even(String threadName){
_threadName = threadName;
_t = new Thread(this);
}
@Override
public void run(){
for (int i = 0; i < 20; i++){
if (i % 2 == 0){
synchronized (Constants.lock){
try{
Constants.lock.wait();
Constants.lock.notifyAll();
}
catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(_threadName + " " + i + " ");
}
}
}
}
}
public class Odd implements Runnable{
Thread _t;
String _threadName;
public Odd(String threadName){
_threadName = threadName;
_t = new Thread(this);
}
@Override
public void run(){
for (int i = 0; i < 20; i++){
if (i % 2 == 1){
synchronized (Constants.lock){
try{
Constants.lock.wait();
Constants.lock.notifyAll();
}
catch (InterruptedException e1){
e1.printStackTrace();
}
System.out.println(_threadName + " " + i + " ");
}
}
}
}
}
我的输出应该是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
谢谢你的帮助,谭。
您正在通过在synchronized
中使用的对象上调用wait来滥用wait
和synchronized
,而没有在循环中同步块内部进行检查。永远不要再这样做了。
事实上,这是发生的事情:
synchronized
线你可以锁定Constants.lock
wait
行,您释放Constants.lock
上的锁并等待来自另一个线程的通知。那么你的编程发生了什么:
synchronized
并继续阻止第二个synchronized
,因为第一个已释放锁定下面的代码将有助于某人,
public class MyClass {
private static Object lock = new Object();
public static void main(String args[]){
Runnable runnable1 = new Runnable() {
@Override
public void run() {
for(int i=1; i<20; i=i+2){
synchronized (lock) {
System.out.println("Thread 1: "+i);
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
System.out.println("Error in Thread 1: "+e.getMessage());
}
}
}
}
};
Runnable runnable2 = new Runnable() {
@Override
public void run() {
for(int i=2; i<=20; i=i+2){
synchronized (lock) {
System.out.println("Thread 2: "+i);
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
System.out.println("Error in Thread 2: "+e.getMessage());
}
}
}
}
};
Thread thread1 = new Thread(runnable1);
Thread thread2 = new Thread(runnable2);
System.out.println("Thread Start: ");
thread1.start();
thread2.start();
}
}
您可以在包声明中提到的站点中找到解释:这是工作代码:
public class MultipleThreading {
int count = 1;
int MAX = 20;
public void printOdd() {
synchronized (this) {
while (count < MAX) {
while (count % 2 == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(count + " ");
count++;
notify();
}
}
}
public void printEven() {
synchronized (this) {
while (count < MAX) {
while (count % 2 == 1) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(count + " ");
count++;
notify();
}
}
}
public static void main(String[] args) {
MultipleThreading mt = new MultipleThreading();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
mt.printEven();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
mt.printOdd();
}
});
t1.start();
t2.start();
}
}
Stack Overflow上的每个人都尝试了相同的解决方案。检查相同的不同实现。
public class PrintSequenceUsingTwo {
public static void main(String[] args) {
ThreadSequence sequence = new ThreadSequence();
Thread t1 = new Thread(()-> {try {
sequence.print();
} catch (InterruptedException e) {
e.printStackTrace();
}},"t1");
Thread t2 = new Thread(()-> {try {
sequence.print();
} catch (InterruptedException e) {
e.printStackTrace();
}},"t2");
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ThreadSequence {
private static int var = 0;
private int limit = 10; //set the variable value upto which you want to print
public synchronized void print() throws InterruptedException {
while (var<limit) {
notify();
System.out.println("Current Thread "+Thread.currentThread().getName()+" Value : "+(++var));
wait();
}
notify();
}
}