002 线程创建 线程启动和停止

线程实践

线程的创建

方式一


public class HelloThread extends Thread {
	public void run() {
		System.out.println("Hello from a thread!");
		}
	public static void main(String args[]) {
		(new HelloThread()).start();
		}
}


方式二


public class HelloRunnable implements Runnable {
	public void run() {
		System.out.println("Hello from a thread!");
		}
	public static void main(String args[]) {
		(new Thread(new HelloRunnable())).start();
	}
}

线程启动和停止

启动线程
调用start方法
停止线程
线程自带的stop方法,一方面已经过时,另一方面,不会对停止的线程做状态保存,使得线程中涉及的对象处于未知状态,如果这些状态,其他线程也会使用,将会使得其他线程出现无法预料的异常,所以,停止程序的功能,需要自己实现。

public class ThreadTest {
	public static void main(String[] args) throws InterruptedException {
		StopThread thread = new StopThread();
		thread.start();
		Thread.sleep(1000L);
		thread.stop();
		while (thread.isAlive()) { }
		thread.print();
	}
	private static class StopThread extends Thread {
		private int x = 0; private int y = 0;
		@Override
		public void run() {
			synchronized (this) {
				++x;
				try {
					Thread.sleep(3000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				++y;
			}
		}
		public void print() {
			System.out.println("x=" + x + " y=" + y);
		}
	}
}

上述代码中,run方法里是一个同步的原子操作,x和y必须要共同增加,然而这里如果调用thread.stop()方法强制中断线程,输出如下:

x=1 y=0

没有异常,也破坏了我们的预期。如果这种问题出现在我们的程序中,会引发难以预期的异常。因此这种不安全的方式很早就被废弃了。

public class MyRunnable implements Runnable {
	private boolean doStop = false;
	public synchronized void doStop() {
		this.doStop = true;
	}
	private synchronized boolean keepRunning() {
		return this.doStop == false;
	}
	@Override
	public void run() {
		while(keepRunning()) {
			// keep doing what this thread should do.
			System.out.println("Running");
			try {
				Thread.sleep(3L * 1000L);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

调用


public class MyRunnableMain {
	public static void main(String[] args) {
		MyRunnable myRunnable = new MyRunnable();
		Thread thread = new Thread(myRunnable);
		thread.start();
		try {
			Thread.sleep(10L * 1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		myRunnable.doStop();
	}
}

上面例子修改

线程进入 run() 方法,并首先检查 keepRunning() 方法的返回值。由于 doStop 初始化为 false,keepRunning() 返回 true,因此线程继续执行。

线程执行 ++x; 后,进入 Thread.sleep(3000L); 的休眠状态。与此同时,主线程执行 Thread.sleep(1000L);,休眠1秒后唤醒,然后调用 thread.doStop();。

然而,thread.doStop(); 只是将 doStop 设置为 true,并不会立即中断正在休眠的线程。线程 StopThread 仍然处于休眠状态,直到3秒后自然唤醒。

当线程唤醒后,它会继续执行 ++y;,因为虽然 doStop() 已经被调用,但是线程是在 synchronized 块内部休眠的,所以在休眠结束并且线程重新获得锁之后,它会继续执行 synchronized 块内的剩余代码。


public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        StopThread thread = new StopThread();
        thread.start();
        Thread.sleep(1000L);
        thread.doStop();
        while (thread.isAlive()) { }
        thread.print();
    }
    private static class StopThread extends Thread {

        private boolean doStop = false;
        public synchronized void doStop() {
            this.doStop = true;
        }
        private synchronized boolean keepRunning() {
            return this.doStop == false;
        }


        private int x = 0; private int y = 0;
        @Override
        public void run() {

            if (keepRunning()) {
                synchronized (this) {
                    ++x;
                    try {
                        Thread.sleep(3000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ++y;
                }
            }
        }
        public void print() {
            System.out.println("x=" + x + " y=" + y);
        }
    }
}



  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 洁 冬冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值