我是这样做这道题的:
package 农金圈;
//两个线程一个打印a-z,一个线程打印A-Z
public class ThreadPrint {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Object obj=new Object();
//新建实例,并启动线程
Thread1 t1=new Thread1(obj);
Thread2 t2=new Thread2(obj);
t1.start();
t2.start();
}
//线程第一步
class Thread1 extends Thread
{
//新建一个代码块进行同步
private Object obj;
public Thread1(Object obj)
{
this.obj=obj;
}
//线程第二步
//重写run()方法
public void run()
{
//要进行同步代码块
synchronized(obj)
{
for(int i=0;i<26;i++)
{
System.out.println((char)('a'+i)+" ");
obj.notifyAll();
try
{
if(i!=25)
{
//当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常
obj.wait();
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
//创立第二个线程
class Thread2 extends Thread
{
private Object obj;
public Thread2(Object obj)
{
this.obj=obj;
}
public void run()
{
synchronized(obj)
{
for(int i=0;i<26;i++)
{
System.out.println((char)('A'+i)+" ");
obj.notifyAll();
try
{
if(i!=25)
{
obj.wait();
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
}
这里告诉我一个错误,一个有关内部类基础的错误。
首先我们要明白一个道理就是有关权限修饰符:public(公开访问权限)、protected(子类访问权限)、default(默认访问权限)、private(当前类访问权限)。
首先我们来明确一下类的基本概念,类分为外部类还有内部类,外部类你既然写在外面那么对应的访问权限,应该就是包还有public,也就是常说到的public和default(默认),在外部类里面加一个内部类,你想想呀,内部类对应的权限是不是private(当前类)还有(子类访问权限),子类访问权限对应的是当前包以及其他包下的子类,public ,default。如果这个时候你用到的是static,那就是静态内部类了。
而我上面的代码很明显,有问题:什么问题呢?
1内部类如果需要加载的话,必须先实例化外部类,然后在用内部类来实现。
2直接用static方法,直接实例化。
3将这个内部类放在与原外部类的外面,相当于没有单独的类的属性。
附上解决2 和解决3的代码,一的还没想出来
package 农金圈;
//两个线程一个打印a-z,一个线程打印A-Z
public class ThreadPrint {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Object obj=new Object();
//新建实例,并启动线程
Thread1 t1=new Thread1(obj);
Thread2 t2=new Thread2(obj);
t1.start();
t2.start();
}
//线程第一步
static class Thread1 extends Thread
{
//新建一个代码块进行同步
private Object obj;
public Thread1(Object obj)
{
this.obj=obj;
}
//线程第二步
//重写run()方法
public void run()
{
//要进行同步代码块
synchronized(obj)
{
for(int i=0;i<26;i++)
{
System.out.println((char)('a'+i)+" ");
obj.notifyAll();
try
{
if(i!=25)
{
//当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常
obj.wait();
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
//创立第二个线程
static class Thread2 extends Thread
{
private Object obj;
public Thread2(Object obj)
{
this.obj=obj;
}
public void run()
{
synchronized(obj)
{
for(int i=0;i<26;i++)
{
System.out.println((char)('A'+i)+" ");
obj.notifyAll();
try
{
if(i!=25)
{
obj.wait();
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
}
package Test;
class Thread1 extends Thread
{
//新建一个代码块进行同步
private Object obj;
public Thread1(Object obj)
{
this.obj=obj;
}
//线程第二步
//重写run()方法
public void run()
{
//要进行同步代码块
synchronized(obj)
{
for(int i=0;i<26;i++)
{
System.out.println((char)('a'+i)+" ");
obj.notifyAll();
try
{
if(i!=25)
{
//当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常
obj.wait();
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
class Thread2 extends Thread
{
//新建一个代码块进行同步
private Object obj;
public Thread2(Object obj)
{
this.obj=obj;
}
//线程第二步
//重写run()方法
public void run()
{
//要进行同步代码块
synchronized(obj)
{
for(int i=0;i<26;i++)
{
System.out.println((char)('a'+i)+" ");
obj.notifyAll();
try
{
if(i!=25)
{
//当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常
obj.wait();
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
public class ThreadPrint {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Object obj=new Object();
//新建实例,并启动线程
Thread1 t1=new Thread1(obj);
Thread2 t2=new Thread2(obj);
t1.start();
t2.start();
}
}
插入一个外文找到答案的图片: