Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
In Java, you can implement multithreading with Threads, Runnable, and Callable
Thread implementation multithreading
Using the Thread method extends the Thread class and then overrides the run function of the parent class, using the start function when executing a multithreaded program.
class sellTicket extends Thread{
private int tickets = 20;
@Override
public void run(a) {
try {
this.sell();
} catch(InterruptedException e) { e.printStackTrace(); }}public void sell(a) throws InterruptedException {
while(tickets>0)
{
System.out.println("Sold a ticket and still has one."+--this.tickets);
Thread.sleep(100); }}}public class testThread {
public static void main(String[] args) throws InterruptedException {
sellTicket st = new sellTicket();
st.start();
int index = 0;
while(true) {
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -");
Thread.sleep(100);
if(index++>30)
break; }}}Copy the code
Without multithreading, the main function would have sold tickets first and then ———-, but with multithreading, the main function and the sellTicket thread run together, resulting in the following result.
Runnable implements multithreading
Multithreading with Runnale is implemented in a similar way to Thread, except that it implements Runnale, new a Thread object, puts the Runnale object into the Thread object, and then starts ().
class sellTicket implements Runnable{
private int tickets = 20;
@Override
public void run(a) {
try {
this.sell();
} catch(InterruptedException e) { e.printStackTrace(); }}public void sell(a) throws InterruptedException {
while(tickets>0)
{
System.out.println("Sold a ticket and still has one."+--this.tickets);
Thread.sleep(100); }}}public class testThread {
public static void main(String[] args) throws InterruptedException {
sellTicket st = new sellTicket();
new Thread(st).start();
int index = 0;
while(true) {
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -");
Thread.sleep(100);
if(index++>30)
break; }}}Copy the code
The result is the same as the previous method
Callable implements multithreading
The call() function is used to perform multithreaded operations on a Callable class. The call() function is used to perform multithreaded operations on a Callable class.
class TestCall implements Callable<String>
{
@Override
public String call(a) throws Exception {
for (int i=0; i<10; i++) { System.out.println(Thread.currentThread().getName()+""+i);
}
return Thread.currentThread().getName() + "Finish thread operation"; }}public class testThread {
public static void main(String[] args) throws InterruptedException, ExecutionException {
TestCall t1 = new TestCall();
TestCall t2 = new TestCall();
TestCall t3 = new TestCall();
// Create the execution service
ExecutorService service = Executors.newFixedThreadPool(3);
// Commit execution
Future<String> r1 = service.submit(t1);
Future<String> r2 = service.submit(t2);
Future<String> r3 = service.submit(t3);
// Get the result
String rs1 = r1.get();
System.out.println(rs1);
String rs2 = r2.get();
System.out.println(rs2);
String rs3 = r3.get();
System.out.println(rs3);
// Shut down the serviceservice.shutdownNow(); }}Copy the code
The result is shown below
Unlike Runnable, Callable cannot be placed directly into the Thread class to execute the start method. It can be mediated by FutureTask.
public class ConcurrentTools {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread thread = new MyThread();
FutureTask futureTask = new FutureTask(thread);
new Thread(futureTask,"A").start();
new Thread(futureTask,"B").start();// The results are cached and printed only once
Integer i = (Integer) futureTask.get();// Get blocks and is best done lastSystem.out.println(i); }}class MyThread implements Callable<Integer>
{
@Override
public Integer call(a) throws Exception {
System.out.println("call");
return 123; }}Copy the code
The difference between Thread and Runnable
- Runnable is implemented by implementing its interface
- Threads are implemented by inheriting their classes
- Thread implements the Runnable interface and extends it. In essence, Thread and Runnable are implementation relations, not homogeneous things, so there is no comparison between Runnable and Thread.
Beginners may have the illusion that Runnable makes it easier to share resources between threads than threads, but this is not the case.
This is a piece of multithreaded code written in Runnable mode
class sellTicket implements Runnable{
static int tickets = 20;
static Object o = new Object();
@Override
public void run(a) {
try {
this.sell();
} catch(InterruptedException e) { e.printStackTrace(); }}public void sell(a) throws InterruptedException {
while (tickets > 0) {
synchronized (o) {
if(tickets<=0)
break;
System.out.println(Thread.currentThread().getName() + "Sold a ticket and still has one." + --this.tickets);
Thread.sleep(100); }}}}public class testThread {
public static void main(String[] args) throws InterruptedException, ExecutionException {
sellTicket st1 = new sellTicket();
sellTicket st2 = new sellTicket();
sellTicket st3 = new sellTicket();
new Thread(st1,"1").start();
new Thread(st2,"2").start();
new Thread(st3,"3").start(); }}Copy the code
Then change the previous code to Thread as follows
public class testThread {
public static void main(String[] args) throws InterruptedException, ExecutionException {
sellTicket st1 = new sellTicket();
sellTicket st2 = new sellTicket();
sellTicket st3 = newsellTicket(); st1.start(); st2.start(); st3.start(); }}class sellTicket extends Thread{
static int tickets = 20;
static Object o = new Object();
@Override
public void run(a) {
try {
this.sell();
} catch(InterruptedException e) { e.printStackTrace(); }}public void sell(a) throws InterruptedException {
while (tickets > 0) {
synchronized (o) {
if(tickets<=0)
break;
System.out.println(Thread.currentThread().getName() + "Sold a ticket and still has one." + --this.tickets);
Thread.sleep(100); }}}}Copy the code
Therefore, no matter which way can realize the resource sharing between multiple threads, just need to do a good synchronization or lock operation.