一、方法二:实现Runnable接口
(1)自定义类实现Runnable接口
(2)重写run()方法
(3)创建自定义类的对象
(4)创建Thread类的对象,并把步骤(3)的对象作为构造参数
Runnable实现多线程:
class MyRunnable implements Runnable{
@Override
public void run() {
for(int i = 0;i < 100;i ++) {
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
MyRunnable m = new MyRunnable();
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
//自命名
// Thread t1 = new Thread(m,"舒克");
// Thread t2 = new Thread(m,"贝塔");
t1.start();
t2.start();
}
}
二、Runnable的优点:
(1)可以避免由于Java单继承带来的局限性
(2)适合所个相同程序的代码去处理同一资源的情况,把线程同程序的代码,数据有效分离较好的体现了面向对象的设计思
三、案例:电影院有三个窗口出售一百张电影票
多线程实现:
class SellTickets implements Runnable{
private int tickets = 100;
//创建锁对象
private Object obj = new Object();
@Override
public void run() {
while(true) {
//当有一个线程进来时其他线程不能进入,实现了同步
synchronized(obj) {//相当于锁住了
if(tickets>0) {
try {
//休息0.1秒
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("现在"+Thread.currentThread().getName()+"窗口正在出售第"
+tickets-- + "张票");
}
}
}
}
}
public class SellTikectsDemo {
public static void main(String[] args) {
SellTickets s = new SellTickets();
Thread t1 = new Thread(s,"1号窗口");
Thread t2 = new Thread(s,"2号窗口");
Thread t3 = new Thread(s,"3号窗口");
t1.start();
t2.start();
t3.start();
}
}
三、同步的特点:
1、前提:多个线程
解决问题的时候要注意:
多个线程使用的是同一个锁对象
2、同步的好处:
同步的出现解决了多线程的安全问题
3、同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率
四、锁:
1、静态代码块的锁是任意对象
2、同步方法的锁是this对象
3、静态方法的锁是类的字节码文件对象
五、匿名内部类实现多线程:
package Demo;
public class ThreadDemo {
public static void main(String[] args) {
//继承Thread类来实现
new Thread() {
@Override
public void run() {
for(int x= 0;x < 100;x ++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}.start();
//实现Runnable接口来实现多线程
new Thread(new Runnable() {
@Override
public void run() {
for(int x= 0;x < 100;x ++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}) {
}.start();
}
}