一、创建线程的第二种方法
Runnable的出现仅仅是将线程的任务进行了对象的封装
*/
class Demo implements Runnable
{
public void run()
{
show();
}
public void show()
{
for(int i = 0;i<10;i++)
{
System.out.println(Thread.currentThread().getName()+"i = "+i);
}
}
}
public class Main
{
public static void main(String[] args)
{
//定义线程的方式
Demo jo = new Demo();
//Thread中有一个Thread(Runnable t)的方法
Thread aThread = new Thread(jo);
//如果不传递,start只会执行自己的方法
Thread bThread = new Thread(jo);
aThread.start();
bThread.start();
}
}
实现Runnable接口的好处:
1.将线程的任务同线程的子类中分离出来,进行了单独的封装,也就是将任务封装成了对象
2.避免了单继承的局限性
所以,创建线程的第二种方式较为常用。
三、代码实例:
第一种线程的创建方式
/*
* 需求:4个窗口进行买票,票数100张,编号1-100
*
*/
class Ticket extends Thread
{
private int num = 100;
//private static int num = 100;
public void run()
{
while(true)
{
if(num>0)
{
System.out.println(Thread.currentThread().getName()+"..sale.."+num--);
}
}
}
}
public class Main
{
public static void main(String[] args)
{
Ticket j1 = new Ticket();
Ticket j2 = new Ticket();
Ticket j3 = new Ticket();
Ticket j4 = new Ticket();
j1.start(); j2.start();
j3.start(); j4.start();
}
}
第二种创建线程的方式
/*
* 需求:4个窗口进行买票,票数100张,编号1-100
*
*/
class Ticket implements Runnable
{
private int num = 100;
//private static int num = 100;
public void run()
{
while(true)
{
if(num>0)
{
System.out.println(Thread.currentThread().getName()+"..sale.."+num--);
}
}
}
}
public class Main
{
public static void main(String[] args)
{
/*
Ticket t = new Ticket();//将 卖票这一行为封装成对象
Thread j1 = new Thread(t);
Thread j2 = new Thread(t);
Thread j3 = new Thread(t);
Thread j4 = new Thread(t);
j1.start(); j2.start();
j3.start(); j4.start();
*/
//两种票,站票、坐票
Ticket zhanpiao = new Ticket();
Ticket zuopiao = new Ticket();
//1 2窗口卖站票,3 4 窗口卖坐票
Thread j1 = new Thread(zhanpiao);
Thread j2 = new Thread(zhanpiao);
Thread j3 = new Thread(zuopiao);
Thread j4 = new Thread(zuopiao);
j1.start(); j2.start();
j3.start(); j4.start();
}
}
public void run()
{
while(true)
{
if(num>0)
{
System.out.println(Thread.currentThread().getName()+"..sale.."+num--);
}
}
}
class Ticket implements Runnable
{
private int num = 100;
//private static int num = 100;
public void run()//此处不能throws,因为Runnable没有声明异常
{
while(true)
{
if(num>0)
{
//睡10毫秒,sleep可能存在异常
//所以只能try,catch,不能抛
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
// TODO: handle exception
}
System.out.println(Thread.currentThread().getName()+"..sale.."+num--);
}
}
}
}
public class Main
{
public static void main(String[] args)
{
Ticket t = new Ticket();
Thread j1 = new Thread(t);
Thread j2 = new Thread(t);
Thread j3 = new Thread(t);
Thread j4 = new Thread(t);
j1.start(); j2.start();
j3.start(); j4.start();
}
}
这就出现了安全隐患,所以在写多线程时,必须考虑安全问题
五、线程安全问题产生的原因:
1.多个线程在操作共享的数据(4个窗口操作共享的num)
2.操作共享数据的线程代码有多条
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与运算,就会导致线程安全问题的产生
(举个简单的例子就是,1号窗口在卖1号票的时,还没卖完,2号窗口就把1号票卖完了,这就会出现卖0号票的情况,如果不try。。直接卖一般不会出事)
JAVA学习第二十三课(多线程(二))- (多线程的创建方式二 :实现Runnable接口(常用))
原文:http://blog.csdn.net/wjw0130/article/details/39936103