进程与线程
1、 进程是程序的一次动态执行过程,它经历了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程
2、 线程Thread是进程下更小的执行单位,同一进程下的多个线程可以同时执行,叫多线程
线程的使用
1、 线程可以通过继承Thread类或Runnable接口来实现,线程启动后会默认调用类中的run方法,如下
class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name = name;
}
//线程默认调用的方法
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}
2、 使用Thread定义线程,并使用
class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name = name;
}
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}
publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread("thread one");
MyThread t2 =new MyThread("thread two");
t1.run();
t2.run();
}
}
执行后发现,程序在按顺序执行,显然多线程并没有启动。要启动线程,需要将t1.run()与t2.run()修改为t1.start()和t2.start()才可以,start表示启动线程,而线程启动后会直接去调用类中的run()方法。
3、 使用Runnable定义线程,并使用
class MyThread implements Runnable{
private String name;
public MyThread(String name){
this.name = name;
}
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}
publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread("thread one");
MyThread t2 =new MyThread("thread two");
Thread td1 =new Thread(t1); //启动仍需通过Thread对象
Thread td2 =new Thread(t2); //启动仍需通过Thread对象
td1.start();
td2.start();
}
}
Runnable接口定义的线程如果要启动仍然需要通过Thread对象,这是主要的区别
4、 Thread类与Runable接口的区别
一个类如果继承了Thread类,则多线程不适合进行资源共享;而实现了Runnable接口则可以方便的实现资源共享
可以通过Thread.currentThread().getName()获取当前线程对象和线程名称
继承Thread类如下,共5张票,但是每个线程都卖出了5张票,这是不对的
class MyThread extends Thread{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()
+" sold ticket: "+ ticket--);
}
}
}
}
publicclass hello{
publicstaticvoid main(String args[]){
//声明了两个线程对象,两个线程都拥有自己单独的资源
MyThread t1 =new MyThread();
MyThread t2 =new MyThread();
//分别启动两个线程,因为两个线程的资源不是共享的
//所以每个线程会发5张票,这就不对了
t1.start();
t2.start();
}
}
实现Runnable接口的类如下,共5张票,两个线程共输出5张票,结果正确
通过Thread.currentThread()可获取当前线程对象
通过Thread.currentThread().getName()可以获取当前线程对象名
class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()
+" sold ticket: "+ ticket--);
}
}
}
}
publicclass hello{
publicstaticvoid main(String args[]){
//声明一个资源对象
MyThread t1 =new MyThread();
//启动两个线程,两个线程共享t1内的资源,实现资源共享
Thread td1 =new Thread(t1);
Thread td2 =new Thread(t1);
td1.start();
td2.start();
}
}
JVM、进程与线程
1、 Java编写的程序都运行在jvm中,每一个程序启动时,都会启动一个JVM,这个JVM实际上就是进程
2、 一个java程序至少启动两个线程,一个是main函数线程,一个是程序的垃圾收集线程
线程状态
1、 创建:Thread t =new Thread();
2、 就绪:t.start();线程启动后就进入操作系统排队,排到了就调用run方法运行
3、 运行:t.run(); 由系统调用运行
4、 堵塞:sleep();suspend();wait()时,线程暂停执行
5、 死亡:stop()或run()结束时
线程同步与死锁
1、 实现了Runnable接口的类,类中的属性由多个线程共享,这时如果多个线程同时操作一个资源时就会出问题,所以出现了线程同步问题,如下
class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
try{
//sleep后线程紧密排队,导致资源争抢
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);
}
}
}
}
publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread();
Thread td1 =new Thread(t1);
Thread td2 =new Thread(t1);
td1.start();
td2.start();
}
}
2、 线程同步,指同一时间内,只允许一个线程对资源进行操作,其它线程排队直到前一个线程完成
3、 同步代码块,synchronized(同步对象){需同步代码},如下
class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
//同步其中的代码块,防止资源争抢,一般使用this,意思是对当前对象进行同步
//同一时间只允许一个线程访问this(当前)对象,而this对象中包含共享资源ticket
synchronized(this){
if(ticket>0){
try{
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);
}
}
}
}
}
4、 同步方法,锁定了该方法同一时间只能有一个线程对其进行调用,如下
class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
sale();
}
}
//同步方法,
privatesynchronizedvoid sale(){
if(ticket>0){
try{
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket : "+ ticket--);
}
}
}
同步与死锁
1、 当需要解决资源共享时,要使用同步来解决
2、 当同步过多时,会出现死锁问题
标签:run,name,Thread,MyThread,线程,进程,ticket From: https://blog.51cto.com/u_15906220/5920666