线程

1.线程是进程中的执行单元。一个进程至少要有一个线程,一个进程中可以有多个线程。

  简而言之:一个程序运行后至少有一个进程,而一个进程中可以有多个线程。

 

创建线程的第一种方法:(继承Thread类,然后重写run方法,然后调用start()方法)

public class MyThread extends Thread {
    @Override
    public void run() {
        for(int i =0;i<=20;i++) {
            System.out.println("My Thread:"+i);
        }
    }
}
public static void main(String[] args) {
     MyThread thread = new MyThread();
     thread.start();        
     for(int i =0;i<=20;i++) {
            System.out.println("Main:"+i);
     }
}

创建线程的第二种方式:

(实现Runnable接口,new一个Thread实例,再把这个Runnable的实例传给Thread的构造方法,再调用start()方法)

public class RunnableImpl implements Runnable{
    @Override
    public void run() {
        System.out.println("第二种创建线程的方式:"+Thread.currentThread().getName());
        
    }
}
public static void main(String[] args) {
    RunnableImpl run = new RunnableImpl();
    Thread t = new Thread(run);
    t.start();
}

 

 Thread中的常用方法:

1.获取当前线程的名字:

    public void run() {
        //方式一:
        String name = getName();
        System.out.println(name);
        
        //方式二:
        System.out.println(Thread.currentThread().getName());//如果是主线程,则需要用到这个方法。
    }

2.设置线程的名称:

两种方式:

  1. 直接调用setName()方法
  2. 重写构造方法,把name传给父类方法。
    MyThread thread1 = new MyThread();
        //方式一:
        thread1.setName("Hello");
        thread1.start();
//方式二:    
    public MyThread(String name) {
        super(name);
    }
    MyThread thread = new MyThread("World");
    thread.start();

 线程安全问题:

当几个线程在操作一个数据的时候,容易造成数据安全问题。

比如三个窗口同时在售票,这个时候就需要用到synchronized 关键字,同步代码块或者同步方法

public class TestSynchronized {

    public static void main(String[] args) {
        SellThread sellThread = new SellThread();
        new Thread(sellThread).start();
        new Thread(sellThread).start();
        new Thread(sellThread).start();        
    }
}
public class SellThread implements Runnable{
    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while(true) {
            synchronized(obj){
                if(ticket>0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"--->"+ticket);
                    ticket--;
                }else{
          
  System.out.println("The tickets have been sold out");
break;
          }
            }                
        }        
    }
}

 利用匿名内部类启动线程:

  1. 第一种方式:创建Thread()对象
  2. 第二种方式:实现Runnable接口
 1 public class InnerClassTestThread {
 2 
 3     public static void main(String[] args) {
 4         new Thread() {
 5             @Override
 6             public void run() {
 7                 System.out.println(Thread.currentThread().getName()+"-->子线程1");
 8             }
 9         }.start();
10         new Thread(new Runnable() {
18             @Override
19             public void run() {                
20                 System.out.println(Thread.currentThread().getName()+"-->子线程2");
21             }
22         }).start();
23         
24         System.out.println(Thread.currentThread().getName()+"-->主线程");
25 
26     }
27 }

 

线程的几种状态:new,runnable,block,waiting,timed_waiting,terminated

 

 

 

 

sleep()和wait()方法的区别:

1.wait()方法是Object类中的方法,sleep()是Thread类里面的静态方法。

2.wait()等待的时候是释放锁等待,而sleep()是抱着锁等到,一旦睡眠时间到,则具有cpu执行权,进入就绪状态。

3.wait()必须写在同步代码块中,而sleep可以在任何地方使用。

 

 

 

 

 

守护线程会因为用户线程执行完毕而自动完成

public class DaemonTest {

    public static void main(String[] args) {
        Thread thread = new Thread(new DaemonThread(),"Daemon");
        thread.setDaemon(true);
        thread.start();
        new Thread(new UserThread(),"User").start();


    }

}
class DaemonThread implements Runnable{

    @Override
    public void run() {
        int i = 0;
        while(true) {
            System.out.println(Thread.currentThread().getName() + "->"+ i++);
        }        
    }
}

class UserThread implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<=1000;i++) {
            System.out.println(Thread.currentThread().getName()+"->"+ i);
        }
    }
    
}

Daemon->57
Daemon->58
User->91
User->92
User->93
User->94
User->95
User->96
User->97
Daemon->59
Daemon->60
Daemon->61
Daemon->62
Daemon->63
User->98
Daemon->64
User->99
Daemon->65
Daemon->66
Daemon->67
User->100
Daemon->68
Daemon->69
Daemon->70
Daemon->71
Daemon->72
Daemon->73
Daemon->74
Daemon->75
Daemon->76
Daemon->77
Daemon->78
UserFinished
Daemon->79
Daemon->80
Daemon->81
Daemon->82
Daemon->83
Daemon->84

 多个线程访问同一个资源叫:并发

如果某些线程需要修改这个对象,就需要做线程同步,怎么做到线程同步,就是排队等待(队列)+锁

 

posted @ 2020-11-09 18:03  Joyce502  阅读(136)  评论(0)    收藏  举报