线程有两种创建方式:
1, 继承Thread类,覆写Run方法。建立子类对象的同时线程也被创建。
2, 实现Runnable接口,再通过Thread类创建线程,并将事先了Runnable接口的子类对象作为参数传递给Thread类的构造函数。使用匿名内部类来写。
方法一源码:
class ThreadDemo extends Thread{
private String name;
private int num =100;
public ThreadDemo(String name){
super();
this.name=name;
}
public void run(){
for(int i=0;i<num;i++){
System.out.println(name+"发了"+i+"份传单");
}
}
方法二:
class MyThread implements Runnable{
private String name;
public MyThread(String name) {
super();
this.name =name;
}
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(name+"发了"+i+"礼物");
}
}
}
线程安全问题:有可能出现问题的三种情况:1,多线程,2有共享数据,3有多条语句操作共享数据。
源码:
class MyThread implements Runnable{
int num =100;
private String name;
public MyThread(){}
public MyThread(String name) {
super();
this.name =name;
}
@Override
public void run() {
for(int i=0;i<200;i++){
synchronized (this) {
if(num>0){
System.out.println(Thread.currentThread().getName()+"发了"+num--+"礼物");
}}
}
}
}
public class Test4 {
public static void main(String[] args) {
MyThread my =new MyThread();
new Thread(my,"ddss").start();
new Thread(my,"sssa").start();
}
}
分析:这个是典型的多线程问题,使用了synchronized来锁住代码块。1,多线程:主程序中new了2个线程。2,有共享数据:线程处理了都是My的对象,而这个类是实现卖票的功能,有共同的数据。3,有多条语句操作共同数据,这是显然的。
解决方法:除了用synchronized来锁住代码块以外,还可以用synchronized来修饰方法,把该方法锁住。
当线程进该程序块后,必须得全部执行完毕,其他线程才能执行,就不会出现抢占问题和数据错误。