java之多线程
程序员文章站
2023-12-23 14:03:40
...
继承Thread,并重写run方法,start()开始,进程为抢占式
MyThread mt = new MyThread(); //添加一个新线程进入cpu抢占资源
mt.start();
for (int i = 0; i < 100; i++) {
System.out.println("main: "+i);
}
创建一个进程的第二种方法,实现Runnable接口,重写run方法
public static void main(String[] args) {
MyThreadRunnable mt = new MyThreadRunnable();//实现了Runnable接口
Thread t = new Thread(mt);
// mt.start(); mt没有start方法要转换成Thread
t.start();
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+": "+i);
}
}
好处:避免了单继承的局限性,增强了程序的扩展性,降低了程序的耦合性,多用这种方式
线程安全问题:用线程同步技术解决
同步代码块:
Object obj = new Object();
@Override
public void run() {
while (true){
synchronized (obj){ //同步代码块,解决线程安全问题
if(ticket>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
ticket--;
}
}
}
}
解决线程安全问题的二种方案:使用同步方法使用步骤:
1.把访问了共享数据的代码抽取出来,放到一个方法中
2.在方法上添加 Synchronized修饰符
格式:定义方法的格式
修饰符 synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}
public synchronized void payTickt(){
if(ticket>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
ticket--;
}
}
第三种方式lock锁
public class LockThread implements Runnable{
private int ticket = 100;
Lock l = new ReentrantLock();
@Override
public void run() {
while (true){
l.lock();
if(ticket>0){
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
l.unlock();
}
}
}
}
}
等待和唤醒Object obj.wait()和Object obj.notify 只有锁对象obj才可以使用wait和notify
线程池:jdk1.5以后有提供现成的线程池
java.utt. concurrent, Executors:线程池的工厂类,用来生成线程池
/*
线程池的使用步骤
1.使用线程池的工厂类 Executors里边提供的静态方法 newFixedThreadpooL生产一个指定线程数量的线程池
2.创建一个类,实现 Runnable接口,重写run方法,设置线程任务
3.调用 Executorservice中的方法 submit,传递线程任务(实现类),开启线程,执行run方法
4.调用 Executonservice中的方法 shutdown销毁线程池(不建议执行)
*/
public class DemoThreadPool {
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(2);
es.submit(new RunnableImpl());
es.submit(new RunnableImpl());
es.submit(new RunnableImpl());
es.shutdown();
}
}