创建线程的两种方式
1.继承Thread。
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("线程开始执行");
System.out.println("线程的名字是"+Thread.currentThread().getName());
}
public static void main(String[] args) {
MyThread m1=new MyThread();
m1.setName("线程A");
m1.start();
MyThread1 m2=new MyThread1();
m2.setName("线程B");
m2.start();
}
}
2.实现 Runnable 接口
package com.thread;
public class Test implements Runnable{
@Override
public void run() {//重写run方法
for (int i = 0; i < 50; i++) {
try {
Thread.sleep(1000);//线程睡眠1秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"----"+i);//获得当前线程的名字
}
}
public static void main(String[] args) {
Thread t1=new Thread(new Test(),"T1线程");
t1.setPriority(1);//设置优先级1-10,默认为5.
t1.start();
Thread t2=new Thread(new Test(),"T2线程");
t2.setPriority(10);
t2.start();
}
}
3. 继承Thread和实现Runnable的区别
-
首先,java只能单继承,因此如果是采用继承Thread的方法,那么在以后进行代码重构的时候可能会遇到问题,因为你无法继承别的类了。其次,如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
-
继承Thread——多线程执行各自的资源,线程执行的资源互不干涉,各自执行各自的。
-
实现Runnable接口——多线程共享同一资源。
线程与进程的区别:进程是资源分配最小单位,线程是程序执行的最小单位。
4. 线程的状态
5.线程的常用方法(线程的调度)
//更改线程执行的优先级。1——10。默认是5。线程被执行的概率大
void setPriority(int newPriority)
//让线程休眠在指定的毫秒数内
static void sleep(long millis)
//线程终止,谁调用,让谁执行。
void join() //例: t1.join在main线程中。main线程停止,等待t1执行完后,再执行main线程
//暂停线程的执行。放弃时间片,重新竞争时间片
static void yield()
//中断线程
void interrupt()
//测试线程是否处于活动状态
boolean isAlive()
6. 同步代码块
- 同一时刻只能有一个线程访问synchronized(this)同步代码块。
-
当一个线程访问一个synchronized(this)同步代码块时,其他synchronized(this)同步代码块同样被锁定
-
当一个线程访问一个synchronized(this)同步代码块时,其他线程可以访问该资源的非 synchronized(this)同步代码块
package com.thread;
public class TestThread5 implements Runnable{
int number=10;
public synchronized void test() {
}
@Override
public void run() {
while(true) {
synchronized (this) {
if(number==0) {
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
number--;
System.out.println(Thread.currentThread().getName()+"剩余票数"+number);
}
}
}
public static void main(String[] args) {
TestThread5 TestThread5=new TestThread5();//必须要使用一个对象,里面的多个线程
Thread t1=new Thread(TestThread5,"张三");
Thread t2=new Thread(TestThread5,"李四");
t1.start();
t2.start();
}
}
7. 常见的线程安全与不安全
- ArrayList的add()方法为非同步方法
- Hashtable为线程安全,键和值都不能为空。HashMap为非线程安全,键和值都可以为空
- StringBuffer线程安全。StringBuilder线程不安全