最近发现了一个有意思的线程区分
public class MyThreadClass {
public static void main(String[] args) {
final MyThreadClass my=new MyThreadClass();
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
try {
my.test1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“test1”);
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
try {
my.test2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“test2”);
thread1.start();
thread2.start();
}
public void test1() throws InterruptedException{
synchronized (this) {
int i=0;
while(i++<=5){
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(500);
}
wait(1000);
while(i++<10)
{
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public void test2() throws InterruptedException{
synchronized(this)
{
int i=0;
while(i++<=5){
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(500);
}
wait(1000);
while(i++<10)
{
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
这种情况下线程会先执行其中一个线程,假设执行thread1中程序,执行到wait之前停止,然后执行thread2,执行到wait停止,然后继续执行thread1未完成的部分,执行完thread1后执行thread2中未完成的部分,输出结果如下
test2:1
test2:2
test2:3
test2:4
test2:5
test2:6
test1:1
test1:2
test1:3
test1:4
test1:5
test1:6
test2:8
test2:9
test2:10
test1:8
test1:9
test1:10
而如果将函数放入匿名类的定义中,看似等价的修改一下,此时函数中变成了thread1与thread2交替运行,
public class MyThreadClass {
public static void main(String[] args) {
final MyThreadClass my=new MyThreadClass();
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
try {
synchronized (this) {
int i=0;
while(i++<=5){
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(500);
}
wait(1000);
while(i++<10)
{
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“test1”);
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
try {
synchronized(this)
{
int i=0;
while(i++<=5){
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(500);
}
wait(1000);
while(i++<10)
{
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“test2”);
thread1.start();
thread2.start();
}
}
运行结果如下
test2:1
test1:1
test1:2
test2:2
test1:3
test2:3
test2:4
test1:4
test1:5
test2:5
test1:6
test2:6
test1:8
test2:8
test1:9
test2:9
test1:10
test2:10
原因其实很简单,未加入时thread1与thread2加锁的是主线程,所以此时thread1给主线程加锁之后thread2无法运行,而第二种方法加锁的是thread1与thread2这两个单独的线程,此时thread1加锁之后thread2仍然能运行。